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

# API Membuat Workflow: Bangun Alur Verifikasi KYC

> Buat workflow verifikasi Didit lewat API. KYC, KYB, AML, dan biometrik dalam satu alur berurutan. Bayar per panggilan, tanpa kontrak.



Prompt API Pembuatan Alur Kerja
        Salin prompt ke papan klip



      
      

\<pre>

\`Create a simple Didit workflow through the Management API.

Endpoint:
POST https://verification.didit.me/v3/workflows/

Authentication:
Use the x-api-key header with my Didit API key.

Requirements:
\- Use the simple v3 API shape with features.
\- Send features in the exact order users should complete them.
\- Do not send workflow_graph, branches, actions, webhooks, or conditional logic.
\- Didit will convert the features array into a linear node-based workflow and add the final status step automatically.
\- Use uppercase feature values such as OCR, LIVENESS, FACE_MATCH, AML, QUESTIONNAIRE, EMAIL_VERIFICATION, PHONE_VERIFICATION, or PROOF_OF_ADDRESS.
\- Configure each feature with the fields from /management-api/workflows/feature-configs.
\- For an OCR feature, omit config.documents_allowed or send an empty object to allow every supported document type. Send config.documents_allowed only to restrict the allowed documents.
\- Put dependency features first. For example, put OCR before FACE_MATCH, NFC, DATABASE_VALIDATION, or user AML checks that depend on document data.
\- For a QUESTIONNAIRE feature, first create the questionnaire with POST /v3/questionnaires/ and use the returned questionnaire_id as config.questionnaire_uuid.
\- Store the workflow uuid returned by the response. Use it as workflow_id when creating sessions and as settings_uuid when updating this workflow.

Example KYC request body:
\{
"workflow_label": "Standard KYC",
"features": [
\{
  "feature": "OCR",
  "config": {
    "documents_allowed": {
      "USA": {
        "DL": {
          "enabled": 1,
          "sides": 2
        }
      }
    },
    "duplicated_user_action": "REVIEW"
  }
},
\{
  "feature": "LIVENESS",
  "config": {
    "face_liveness_method": "PASSIVE"
  }
},
\{
  "feature": "FACE_MATCH"
}
]
}

Example questionnaire workflow body:
\{
"workflow_label": "Source of Funds",
"features": [
\{
  "feature": "QUESTIONNAIRE",
  "config": {
    "questionnaire_uuid": "11111111-2222-3333-4444-555555555555",
    "review_questionnaire_manually": true
  }
}
]
}

Build the API call, handle validation errors, and return the workflow uuid from the response.`

\</pre>



      
      

Tempel ke

Gunakan endpoint ini untuk membuat alur kerja melalui API tanpa perlu membangun node graf alur kerja sendiri. Kirim array `features` sesuai urutan pengguna harus menyelesaikan pemeriksaan tersebut. Didit mengubahnya menjadi alur kerja berbasis node secara internal dan menambahkan langkah status akhir secara otomatis.Endpoint `POST /v3/workflows/` ini hanya membuat alur kerja **sederhana dan linear**, yaitu daftar `features` yang datar. Untuk **percabangan, perutean kondisional, Document AI, serta node keputusan dan penolakan**, gunakan **[format graf](#percabangan-&-alur-kerja-berbasis-node-graf)** yang dijelaskan di bawah. Format ini digunakan oleh pembangun visual di konsol dan alat alur kerja [Didit MCP](https://docs.didit.me/id/integration/mcp/overview.md).Lihat [Konfigurasi Fitur Alur Kerja](https://docs.didit.me/id/management-api/workflows/feature-configs.md) untuk setiap kolom `config` yang diterima oleh setiap fitur.## Alur kerja KYC dasar```json theme={null}
{
  "workflow_label": "Standard KYC",
  "features": [
    {
      "feature": "OCR",
      "config": {
        "documents_allowed": {
          "USA": {
            "DL": {
              "enabled": 1,
              "sides": 2
            }
          }
        },
        "duplicated_user_action": "REVIEW"
      }
    },
    {
      "feature": "LIVENESS",
      "config": {
        "face_liveness_method": "PASSIVE"
      }
    },
    {
      "feature": "FACE_MATCH"
    }
  ]
}
```## Alur kerja kuesionerPertama, buat kuesioner dengan `POST /v3/questionnaires/`. Kemudian gunakan `questionnaire_id` yang dikembalikan sebagai `questionnaire_uuid`.```json theme={null}
{
  "workflow_label": "Source of Funds",
  "features": [
    {
      "feature": "QUESTIONNAIRE",
      "config": {
        "questionnaire_uuid": "11111111-2222-3333-4444-555555555555",
        "review_questionnaire_manually": true
      }
    }
  ]
}
```Urutan fitur itu penting. Misalnya, tempatkan `OCR` sebelum `FACE_MATCH`, `NFC`, `DATABASE_VALIDATION`, atau pemeriksaan AML pengguna yang bergantung pada data dokumen.## Referensi konfigurasi fiturSetiap item `features[]` memiliki bentuk berikut:```json theme={null}
{
  "feature": "OCR",
  "label": "ID Verification",
  "config": {}
}
```Objek `config` yang tepat bergantung pada fiturnya. Tinjau daftar kolom lengkap, nilai default, pengaturan wajib, rentang nilai, dan contoh di [Konfigurasi Fitur Alur Kerja](https://docs.didit.me/id/management-api/workflows/feature-configs.md).Untuk `OCR`, hilangkan `config.documents_allowed`, kirim `null`, atau kirim `{}` untuk mengizinkan semua jenis dokumen yang didukung. Sertakan kolom ini hanya jika Anda ingin membatasi alur kerja ke negara atau jenis dokumen tertentu. Untuk `QUESTIONNAIRE`, `config.questionnaire_uuid` wajib diisi.## Pengaturan alur kerja opsionalAnda dapat menyertakan kolom tingkat atas mana pun berikut saat membuat alur kerja untuk mengontrol perilaku sesi. Semua kolom ini bersifat opsional dan akan menggunakan nilai default alur kerja jika dihilangkan.| Kolom | Tipe | Deskripsi |
| - | - | - |
| `is_white_label_enabled` | boolean | Aktifkan kustomisasi White Label untuk sesi yang dibuat dengan alur kerja ini. Default `false`. |
| `is_desktop_allowed` | boolean | Izinkan alur verifikasi berjalan di browser desktop. Default `false`. |
| `max_retry_attempts` | integer (0–10) | Jumlah maksimum percobaan ulang yang diizinkan setelah verifikasi ditolak. `0` memblokir pengguna setelah penolakan pertama. Default `3`. |
| `retry_window_days` | integer (1–365) atau `null` | Periode bergulir dalam hitungan hari yang digunakan untuk menghitung percobaan ulang (`null` = batas sepanjang waktu). Default `7`. |
| `session_expiration_time` | integer (3600–2419200) | Jumlah detik sebelum sesi yang belum selesai kedaluwarsa. Minimum 1 jam, maksimum 4 minggu. Default `604800` (7 hari). |
| `response_attributes` | object atau `null` | Membatasi kolom yang dikembalikan untuk setiap fitur, misalnya `{"id_verifications": ["full_name", "document_number"], "face_matches": null}`. `null` atau kunci yang tidak disertakan akan mengembalikan semua kolom. Daftar kosong hanya mengembalikan `status`, `warnings`, `node_id`, `is_nfc_skipped` dan `skip_reason`, sedangkan kolom lainnya dikembalikan sebagai `null`. |```json theme={null}
{
  "workflow_label": "Standard KYC",
  "is_white_label_enabled": true,
  "is_desktop_allowed": true,
  "max_retry_attempts": 5,
  "retry_window_days": 14,
  "session_expiration_time": 86400,
  "features": [
    { "feature": "OCR" },
    { "feature": "LIVENESS" },
    { "feature": "FACE_MATCH" }
  ]
}
```## Percabangan & alur kerja berbasis node (graf)Daftar `features` yang linear tidak dapat menyatakan "jika X maka Y". Untuk **percabangan bersyarat** (menolak berdasarkan status, mengarahkan berdasarkan kolom yang diekstrak, menahan langkah berdasarkan kecocokan), langkah permintaan **Document AI**, atau node akhir **penolakan/keputusan**, alur kerja Didit menggunakan **graf node**, yaitu struktur yang sama dengan yang dihasilkan pembangun visual di konsol.> [!NOTE]
>
> Cara paling sederhana membuat alur kerja berbasis graf adalah melalui **[Didit MCP](https://docs.didit.me/id/integration/mcp/overview.md)**: minta agen dengan bahasa biasa ("setelah Verifikasi Identitas, jika profesi ≈ 'Software Engineer', tambahkan langkah bukti dana"), dan agen akan membangun, memvalidasi, serta menyimpan graf untuk Anda. Struktur di bawah ini adalah yang dihasilkan oleh alat-alat tersebut (dan konsol).### Bentuk grafGraf berbentuk `{ start_node, nodes }`. `nodes` adalah peta dari id node ke node. Sisi bersifat implisit: setiap node menunjuk ke depan melalui `next` (tanpa syarat) dan/atau `branches[].goto` (bersyarat).| Jenis node | Bentuk |
| - | - |
| `feature` | `{ "node_type": "feature", "feature": "OCR", "config": {…}, "next": "<id>", "branches": [] }` |
| `branch` | `{ "node_type": "branch", "branches": [ { "id", "logic": "and"\|"or", "rules": [<rule>], "goto": "<id>" } ], "next": "<fallback id>" }` |
| `status` (akhir) | `{ "node_type": "status", "session_status": "Approved"\|"Declined"\|"In Review"\|"Determine" }` |
| `action` | `{ "node_type": "action", "actions": [ { "type": "add_tag"\|"add_review"\|… } ], "next": "<id>" }` |
| `webhook` | `{ "node_type": "webhook", "config": { "url", "method" }, "branches": [], "next": "<id>" }` |`start_node` harus berupa node fitur. Cabang dievaluasi secara berurutan, **kecocokan pertama berlaku**; `rules: []` yang kosong adalah "else" penangkap semua (letakkan di urutan terakhir). `session_status: "Determine"` memutuskan secara otomatis dari gabungan hasil fitur.> [!WARNING]
>
> **Setiap node cabang wajib memiliki cabang else yang eksplisit**: cabang dengan `rules: []` yang menangani sesi yang tidak cocok dengan kondisi mana pun. Jangan mengandalkan `next` pada node cabang sebagai cadangan. `next` yang berdiri sendiri ditampilkan sebagai edge yang ambigu di pembangun dan mudah terlewat. Saat Anda mengirim node cabang dengan `next` tetapi tanpa cabang else, API akan **mengubah `next` tersebut menjadi cabang else eksplisit** untuk Anda (sehingga `{ …, "branches": [<conditions>], "next": "liveness" }` disimpan sebagai `branches: [<conditions>, { "id": "else", "rules": [], "goto": "liveness" }]`). Buat else sendiri agar eksplisit. Konversi tersebut hanyalah jaring pengaman, bukan pengganti.### Aturan cabang & operatorSetiap aturan membandingkan **kolom** dengan **nilai** menggunakan **operator**:```json theme={null}
{ "field": "kyc.extra_fields.profession", "operator": "fuzzy_match", "value": "Software Engineer", "score": 80 }
```- **Kolom** menyebutkan hasil fitur (`kyc.status`, `aml.status`, `document_ai.status`, `face_match.score`, …) atau nilai yang diekstrak (`kyc.full_name`, `kyc.age`, `kyc.nationality`, `kyc.extra_fields.profession`, kolom Document AI `document_ai.<key>`, `expected_details.*`). Cabang hanya boleh membaca kolom yang fiturnya telah dijalankan pada setiap jalur yang menuju ke cabang tersebut.
- **Operator:** `equals`, `not_equals`, `greater_than(_or_equals)`, `less_than(_or_equals)`, `contains`, `not_contains`, `in`, `not_in`, `is_empty`, `is_not_empty`, `regex`, dan **`fuzzy_match`** (hanya untuk kolom string; memerlukan `score` 0–100, yaitu ambang kemiripan, misalnya profesi ≥ 80% mirip dengan "Software Engineer").### Cabang berdasarkan alasan NFC tidak dijalankanSetelah node `NFC`, gunakan `nfc.skip_reason` dengan `equals` atau `in` untuk mengarahkan sesi berdasarkan alasan pembacaan chip tidak dilakukan. Kolom ini memiliki tujuh nilai tetap berikut:- `USER_SKIPPED`
- `DOCUMENT_WITHOUT_CHIP`
- `CHIP_CERTIFICATE_UNAVAILABLE`
- `DEVICE_WITHOUT_NFC`
- `INTEGRATION_WITHOUT_NFC_ACCESS`
- `MRZ_KEY_UNAVAILABLE`
- `JPKI_UNAVAILABLE`Lihat [Alasan NFC dilewati](https://docs.didit.me/id/core-technology/nfc-verification/warnings-nfc-verification.md#alasan-pelewatan) untuk arti setiap nilai. Saat NFC berhasil, `nfc.skip_reason` bernilai `null`, sehingga aturan `equals` maupun `in` untuk alasan dilewati tidak akan cocok.Kolom ini juga memiliki nilai untuk node NFC yang **dilewati oleh gerbang**. Ini mencakup kasus ketika tidak ada laporan atau peringatan NFC, dan kasus ketika `allow_nfc_skip` bernilai `false` tetapi gerbang dokumen atau perangkat mencegah NFC dijalankan. Dengan demikian, Anda dapat mengarahkan sesi-sesi ini tanpa bergantung pada entri `nfc_verifications[]`.> [!NOTE]
>
> Sesi yang disimpan sebelum kapabilitas NFC menjadi tiga status dapat memiliki `has_device_nfc_support: false`. Sesi web lama karena itu dapat ditentukan sebagai `DEVICE_WITHOUT_NFC`, bukan `INTEGRATION_WITHOUT_NFC_ACCESS`.Graf ini menggunakan `equals` untuk NFC yang dilewati pengguna, `in` untuk NFC yang dilewati akibat gerbang atau kapabilitas, dan else eksplisit untuk NFC yang berhasil. Cabang berada setelah node `NFC`, dan setiap tujuan menunjuk ke depan ke node akhir:```json theme={null}
{
  "start_node": "ocr",
  "nodes": {
    "ocr": {
      "node_type": "feature",
      "feature": "OCR",
      "next": "nfc"
    },
    "nfc": {
      "node_type": "feature",
      "feature": "NFC",
      "config": { "allow_nfc_skip": false },
      "next": "route_nfc"
    },
    "route_nfc": {
      "node_type": "branch",
      "branches": [
        {
          "id": "user_skipped",
          "logic": "and",
          "rules": [
            { "field": "nfc.skip_reason", "operator": "equals", "value": "USER_SKIPPED" }
          ],
          "goto": "manual_review"
        },
        {
          "id": "nfc_unavailable",
          "logic": "and",
          "rules": [
            {
              "field": "nfc.skip_reason",
              "operator": "in",
              "value": [
                "DOCUMENT_WITHOUT_CHIP",
                "CHIP_CERTIFICATE_UNAVAILABLE",
                "DEVICE_WITHOUT_NFC",
                "INTEGRATION_WITHOUT_NFC_ACCESS",
                "MRZ_KEY_UNAVAILABLE",
                "JPKI_UNAVAILABLE"
              ]
            }
          ],
          "goto": "manual_review"
        },
        {
          "id": "else",
          "logic": "and",
          "rules": [],
          "goto": "approved"
        }
      ]
    },
    "manual_review": { "node_type": "status", "session_status": "In Review" },
    "approved": { "node_type": "status", "session_status": "Approved" }
  }
}
```Untuk menyatakan "NFC tidak dilakukan karena alasan apa pun yang diketahui", gunakan `in` dengan **ketujuh** nilai. Pertahankan cabang else eksplisit untuk NFC yang berhasil (`nfc.skip_reason: null`) serta nilai baru di masa depan yang belum dikenali oleh graf Anda.### Document AI (misalnya bukti dana)Node fitur `DOCUMENT_AI` meminta satu atau beberapa dokumen dan mengekstrak kolom bernama:```json theme={null}
{
  "node_type": "feature",
  "feature": "DOCUMENT_AI",
  "label": "Proof of Funds",
  "config": {
    "document_ai_documents": [
      {
        "document_key": "proof_of_funds",
        "title": "Proof of Funds",
        "description": "Upload a recent bank statement.",
        "fields": [
          {
            "key": "account_holder",
            "name": "Account holder",
            "instruction": "The full name of the account holder as printed on the statement.",
            "type": "text",
            "required": true,
            "is_full_name": true
          },
          {
            "key": "closing_balance",
            "name": "Closing balance",
            "instruction": "The closing balance amount.",
            "type": "number",
            "required": true
          }
        ]
      }
    ],
    "document_ai_missing_required_fields_action": "REVIEW",
    "document_ai_name_mismatch_action": "REVIEW"
  },
  "next": "final_decision"
}
```Setiap kolom yang dikonfigurasi menjadi nilai yang dapat dicabangkan `document_ai.<key>`, dan hasil langkah ini adalah `document_ai.status`.Atur `"is_full_name": true` pada kolom yang memuat nama lengkap pemegang dokumen. Nilai yang diekstrak dibandingkan dengan nama lengkap identitas yang terverifikasi (nama dari OCR/verifikasi ID, atau detail yang diharapkan dari sesi), dan `document_ai_name_mismatch_action` menentukan apa yang terjadi jika ada ketidakcocokan di bawah `document_ai_name_match_score_threshold`. Penanda ini **opsional**: sebuah dokumen boleh tidak menandai kolom apa pun, dan **paling banyak satu kolom per dokumen** boleh mengaturnya. Lihat [Konfigurasi fitur alur kerja → Document AI](https://docs.didit.me/id/management-api/workflows/feature-configs.md#document-ai) untuk setiap kolom konfigurasi Document AI.### Endpoint & siklus hidup drafPengeditan graf dilakukan per aplikasi dan menggunakan endpoint konsol/manajemen (Bearer pengguna + `read:workflows`/`write:workflows`). Graf hanya dapat diedit pada versi **draf**, sehingga siklus hidupnya adalah **buat draf → atur graf → publikasikan**:| Metode | Path | Tujuan |
| - | - | - |
| `GET` | `…/verification-settings/{settings_uuid}/workflow-graph/` | Graf saat ini + `status`/`is_editable` |
| `POST` | `…/application/{app}/workflow-graph/validate/` (body `{ "graph": … }`) | Validasi uji coba (dry-run) |
| `GET` | `…/application/{app}/workflow-graph/field-definitions/` | Kolom yang dapat dicabangkan + operator yang valid |
| `POST` | `…/verification-settings/{settings_uuid}/create-draft/` | Draf yang dapat diedit dari versi yang dipublikasikan |
| `PUT` | `…/verification-settings/{settings_uuid}/workflow-graph/` (body `{ "graph": … }`) | Simpan graf |
| `PATCH` | `…/verification-settings/{settings_uuid}/` (body `{ "status": "published" }`) | Publikasikan draf |#### Peringatan validasiEndpoint validate mengembalikan `{ "is_valid": true, "graph": …, "warnings": [] }`. Peringatan bersifat **anjuran**: graf tetap valid, dapat disimpan, dan dapat dipublikasikan meskipun ada peringatan. Setiap entri memuat node cabang dan jalur yang dimaksud, sehingga pembuat alur dapat menunjuk ke kondisi yang tepat:```json theme={null}
{
  "type": "branch_outcome_contradiction",
  "node_id": "after_ocr",
  "branch_id": "b1",
  "severity": "warning",
  "message": "Branch 1 only matches sessions where ID Verification Status is Approved or In Review, but every path from it ends in the session outcome \"Declined\". Check the condition or the outcome.",
  "params": { "branchNumber": 1, "field": "ID Verification Status", "allowed": "Approved or In Review", "outcome": "Declined" }
}
```| `type` | Arti |
| - | - |
| `branch_outcome_contradiction` | Kondisi jalur dan hasil yang dicapai setiap jalur dari situ saling bertentangan, misalnya `kyc.status NOT EQUALS Declined` diarahkan ke hasil `Declined`. Hasil tersebut bisa berada beberapa langkah lebih jauh di sepanjang jalur. |
| `branch_condition_unreachable` | Jalur ini tidak pernah bisa cocok, karena setiap jalur yang menuju cabang ini sudah membatasi kolom status ke nilai-nilai yang dikecualikan oleh kondisi tersebut. |
| `else_branch_unreachable` | Jalur else tidak pernah bisa dijalankan: jalur lain sudah mencakup setiap nilai yang dapat dimiliki kolom di sini. |Graf yang tidak valid mengembalikan `400` dengan daftar `errors` **dan** daftar `warnings` sebisanya. Hanya `errors` yang menghalangi penyimpanan.### Contoh: arahkan Software Engineers ke bukti dana> Setelah verifikasi identitas: jika hasilnya **ditolak**, tolak sesi; jika **profesi** pemegang ≈ "Software Engineer" (kemiripan minimal 80%), minta dokumen **bukti dana**; lalu buat keputusan akhir.```json theme={null}
{
  "start_node": "ocr_1",
  "nodes": {
    "ocr_1": { "node_type": "feature", "feature": "OCR", "label": "ID Verification", "next": "after_ocr" },
    "after_ocr": {
      "node_type": "branch",
      "label": "Route after ID verification",
      "branches": [
        { "id": "declined", "logic": "or", "rules": [ { "field": "kyc.status", "operator": "equals", "value": "Declined" } ], "goto": "decline" },
        { "id": "software_engineer", "logic": "and", "rules": [ { "field": "kyc.extra_fields.profession", "operator": "fuzzy_match", "value": "Software Engineer", "score": 80 } ], "goto": "proof_of_funds" },
        { "id": "else", "logic": "and", "rules": [], "goto": "final_decision" }
      ]
    },
    "proof_of_funds": {
      "node_type": "feature",
      "feature": "DOCUMENT_AI",
      "label": "Proof of Funds",
      "config": {
        "document_ai_documents": [
          { "document_key": "proof_of_funds", "title": "Proof of Funds", "description": "Upload a recent bank statement.",
            "fields": [
              { "key": "account_holder", "name": "Account holder", "type": "text", "required": true },
              { "key": "closing_balance", "name": "Closing balance", "type": "number", "required": true }
            ] }
        ],
        "document_ai_missing_required_fields_action": "REVIEW"
      },
      "next": "final_decision"
    },
    "final_decision": { "node_type": "status", "session_status": "Determine", "label": "Final decision" },
    "decline": { "node_type": "status", "session_status": "Declined", "label": "Declined" }
  }
}
```Node akhir menggunakan `session_status: "Determine"`, yang **memutuskan secara otomatis** (disetujui / ditolak / dalam peninjauan) berdasarkan fitur yang benar-benar dijalankan pada sesi. Dengan begitu, jalur bukti dana maupun jalur else terselesaikan dengan benar, tanpa cabang mana pun yang membaca `document_ai.status` (kolom yang tidak ada pada jalur yang tidak menjalankan Document AI). Perlu diingat: cabang hanya boleh membaca kolom yang fiturnya dijalankan pada *setiap* jalur yang menuju cabang tersebut.Kirim sebagai `{ "graph": <above> }` ke endpoint `…/workflow-graph/` (validasi dulu). Untuk membangun alur **baru** dari awal, gunakan `didit_workflow_set_graph` pada MCP. Untuk mengubah alur **yang sudah ada**, gunakan `didit_workflow_edit_graph` (operasi kecil yang mempertahankan node dan allow-list yang sudah ada). Lihat [Didit MCP](https://docs.didit.me/id/integration/mcp/tools.md).


## OpenAPI

````yaml id/openapi-25.json POST /v3/workflows/
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
security: []
tags: []
paths:
  /v3/workflows/:
    post:
      tags:
        - Workflows
      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
      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/' \
              -H 'x-api-key: YOUR_API_KEY' \
              -H 'Content-Type: application/json' \
              -d '{
                "workflow_label": "Standard KYC",
                "features": [
                  {"feature": "OCR"},
                  {"feature": "LIVENESS", "config": {"face_liveness_method": "passive"}},
                  {"feature": "FACE_MATCH", "config": {"face_match_score_decline_threshold": 40, "face_match_score_review_threshold": 60}}
                ]
              }'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # Reads DIDIT_API_KEY.
            client = Didit()

            result = client.workflows.create(
                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},
                }],
            )
            print(result)
        - lang: javascript
          label: Node.js
          source: |-
            import Didit from "@didit-protocol/sdk-node";

            // Reads DIDIT_API_KEY.
            const didit = new Didit();

            const result = await didit.workflows.create({
              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 },
              }],
            });
            console.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;

            import java.util.Map;

            import me.didit.Didit;

            import me.didit.types.SimpleWorkflowFeature;

            import me.didit.types.SimpleWorkflowRequest;


            // Reads DIDIT_API_KEY.

            Didit client = new Didit();


            var result =
            client.workflows().create(SimpleWorkflowRequest.builder()
                    .workflowLabel("Standard KYC")
                    .features(List.of(
                            SimpleWorkflowFeature.builder()
                                    .feature(SimpleWorkflowFeature.Feature.of("OCR"))
                                    .config(Map.of("duplicated_user_action", "review"))
                                    .build(),
                            SimpleWorkflowFeature.builder()
                                    .feature(SimpleWorkflowFeature.Feature.of("LIVENESS"))
                                    .config(Map.of("face_liveness_method", "passive"))
                                    .build(),
                            SimpleWorkflowFeature.builder()
                                    .feature(SimpleWorkflowFeature.Feature.of("FACE_MATCH"))
                                    .config(Map.of("face_match_score_decline_threshold", 40, "face_match_score_review_threshold", 60))
                                    .build()))
                    .build());
            System.out.println(result);
        - lang: php
          label: PHP
          source: |-
            <?php

            require 'vendor/autoload.php';

            use Didit\DiditClient;

            // Reads DIDIT_API_KEY.
            $didit = new DiditClient();

            $result = $didit->workflows->create([
                '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],
                ]],
            ]);
            print_r($result->toArray());
        - lang: ruby
          label: Ruby
          source: |-
            require "didit"

            # Reads DIDIT_API_KEY.
            didit = Didit::Client.new

            result = didit.workflows.create(
              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 },
              }]
            )
            puts result.to_h
        - lang: csharp
          label: .NET
          source: >-
            using System;

            using System.Collections.Generic;

            using System.Text.Json;

            using Didit;


            // Reads DIDIT_API_KEY.

            using var client = new DiditClient();


            var result = await client.Workflows.CreateAsync(new
            SimpleWorkflowRequest

            {
                WorkflowLabel = "Standard KYC",
                Features = new SimpleWorkflowFeature[]
                {
                    new()
                    {
                        Feature = "OCR",
                        Config = new Dictionary<string, object> { ["duplicated_user_action"] = "review" },
                    },
                    new()
                    {
                        Feature = "LIVENESS",
                        Config = new Dictionary<string, object> { ["face_liveness_method"] = "passive" },
                    },
                    new()
                    {
                        Feature = "FACE_MATCH",
                        Config = new Dictionary<string, object> { ["face_match_score_decline_threshold"] = 40, ["face_match_score_review_threshold"] = 60 },
                    },
                },
            });

            Console.WriteLine(JsonSerializer.Serialize(result));
components:
  schemas:
    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).
    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
    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.
  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.

````

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