> ## 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：KYCフローを構築

> Didit の認証ワークフローを、機能の順序を指定してプログラムで作成できます。KYC、KYB、AML、生体認証を1つのフローに統合。呼び出しごとの従量課金で、契約は不要です。



ワークフロー作成APIプロンプト
        プロンプトをクリップボードにコピー



      
      

\<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>



      
      

貼り付け先

このエンドポイントを使うと、ワークフローのグラフノードを自分で構築しなくても、APIでワークフローを作成できます。ユーザーにチェックを完了してもらう順序で`features`配列を送信してください。Diditはこれを内部でノードベースのワークフローに変換し、最終ステータスのステップを自動的に追加します。この`POST /v3/workflows/`エンドポイントで作成できるのは、フラットな`features`リストによる**シンプルで直線的な**ワークフローのみです。**分岐、条件付きルーティング、Document AI、却下・判定ノード**を使う場合は、以下で説明するノードの**[グラフ形式](#分岐とノードベースのワークフロー-グラフ)**を使用してください（コンソールのビジュアルビルダーと[Didit MCP](https://docs.didit.me/ja/integration/mcp/overview.md)のワークフローツールもこの形式で動作しています）。各機能が受け付けるすべての`config`フィールドについては、[ワークフロー機能の設定](https://docs.didit.me/ja/management-api/workflows/feature-configs.md)を参照してください。## 基本的なKYCワークフロー```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"
    }
  ]
}
```## アンケートワークフローまず`POST /v3/questionnaires/`でアンケートを作成します。次に、返された`questionnaire_id`を`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
      }
    }
  ]
}
```機能の順序は重要です。たとえば、書類データに依存する`FACE_MATCH`、`NFC`、`DATABASE_VALIDATION`、またはユーザーのAMLチェックより前に`OCR`を配置してください。## 機能設定リファレンス`features[]`の各項目は次の形式です。```json theme={null}
{
  "feature": "OCR",
  "label": "ID Verification",
  "config": {}
}
````config`オブジェクトの正確な内容は機能によって異なります。フィールドの完全な一覧、デフォルト値、必須設定、値の範囲、例については[ワークフロー機能の設定](https://docs.didit.me/ja/management-api/workflows/feature-configs.md)を確認してください。`OCR`では、`config.documents_allowed`を省略するか、`null`または`{}`を送信すると、サポートされているすべての書類タイプが許可されます。特定の国や書類タイプにワークフローを限定したい場合にのみ含めてください。`QUESTIONNAIRE`では、`config.questionnaire_uuid`が必須です。## オプションのワークフロー設定ワークフローの作成時に以下のトップレベルフィールドを含めることで、セッションの動作を制御できます。いずれも任意で、省略した場合はワークフローのデフォルト値が使用されます。| フィールド | 型 | 説明 |
| - | - | - |
| `is_white_label_enabled` | boolean | このワークフローで作成されたセッションで、ホワイトラベルのカスタマイズを有効にします。デフォルトは`false`です。 |
| `is_desktop_allowed` | boolean | デスクトップブラウザでの認証フローの実行を許可します。デフォルトは`false`です。 |
| `max_retry_attempts` | 整数（0–10） | 認証が却下された後に許可される再試行の最大回数です。`0`の場合、最初の却下でユーザーがブロックされます。デフォルトは`3`です。 |
| `retry_window_days` | 整数（1–365）または`null` | 再試行回数のカウントに使用する、日数単位のローリング期間です（`null`は全期間での上限）。デフォルトは`7`です。 |
| `session_expiration_time` | 整数（3600–2419200） | 未完了のセッションが期限切れになるまでの秒数です。最小1時間、最大4週間です。デフォルトは`604800`（7日間）です。 |
| `response_attributes` | オブジェクトまたは`null` | 機能ごとに返されるフィールドを制限します。例: `{"id_verifications": ["full_name", "document_number"], "face_matches": null}`。`null`またはキーが存在しない場合は、すべてのフィールドが返されます。空のリストを指定すると、`status`、`warnings`、`node_id`、`is_nfc_skipped`、`skip_reason`のみが返され、その他のフィールドは`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" }
  ]
}
```## 分岐とノードベースのワークフロー (グラフ)直線的な`features`リストでは「XならばY」という条件を表現できません。**条件分岐**(ステータスに応じた却下、抽出したフィールドに基づくルーティング、一致結果に応じたステップの制御)、**Document AI**のリクエストステップ、または終端の**却下/判定**ノードを使う場合、Diditのワークフローは**ノードグラフ**を使用します。これはコンソールのビジュアルビルダーが生成するものと同じ構造です。> [!NOTE]
>
> グラフワークフローを最も簡単に構築する方法は\*\*[Didit MCP](https://docs.didit.me/ja/integration/mcp/overview.md)\*\*です。エージェントに自然な言葉で依頼する(「本人確認の後、職業が'Software Engineer'に近ければ資金証明のステップを追加して」)と、グラフの構築、検証、保存までを代わりに行います。以下の構造は、これらのツール(およびコンソール)が生成するものです。### グラフの構造グラフは`{ start_node, nodes }`です。`nodes`はノードIDからノードへのマップです。エッジは暗黙的に定義され、各ノードは`next`(無条件)または`branches[].goto`(条件付き)、あるいはその両方で次のノードを指します。| ノードタイプ | 構造 |
| - | - |
| `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`(終端) | `{ "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`は機能ノードでなければなりません。分岐は順番に評価され、**最初に一致したものが採用されます**。空の`rules: []`はすべてに一致する「else」です(必ず最後に置いてください)。`session_status: "Determine"`は、各機能の結果を総合して自動的に判定します。> [!WARNING]
>
> **すべての分岐ノードには明示的なelse分岐が必要です**。これは`rules: []`を持つ分岐で、どの条件にも一致しないセッションのルーティング先を指定します。分岐ノードの`next`をフォールバックとして頼らないでください。単独の`next`はビルダー上で曖昧なエッジとして表示され、見落としやすくなります。else分岐がなく`next`を持つ分岐ノードを送信すると、APIがその\*\*`next`を明示的なelse分岐に変換します\*\*(つまり`{ …, "branches": [<conditions>], "next": "liveness" }`は`branches: [<conditions>, { "id": "else", "rules": [], "goto": "liveness" }]`として保存されます)。明示性を保つため、else分岐は自分で作成してください。この変換はあくまで安全策であり、代わりになるものではありません。### 分岐ルールと演算子各ルールは、**フィールド**と**値**を**演算子**で比較します:```json theme={null}
{ "field": "kyc.extra_fields.profession", "operator": "fuzzy_match", "value": "Software Engineer", "score": 80 }
```- **フィールド**には、機能の結果(`kyc.status`、`aml.status`、`document_ai.status`、`face_match.score`など)または抽出された値(`kyc.full_name`、`kyc.age`、`kyc.nationality`、`kyc.extra_fields.profession`、Document AIのフィールド`document_ai.<key>`、`expected_details.*`)を指定します。分岐が読み取れるのは、その分岐に到達するすべての経路で対応する機能が実行済みのフィールドのみです。
- **演算子:** `equals`、`not_equals`、`greater_than(_or_equals)`、`less_than(_or_equals)`、`contains`、`not_contains`、`in`、`not_in`、`is_empty`、`is_not_empty`、`regex`、および**`fuzzy_match`**(文字列フィールドのみ。0–100の`score`が必須で、これは類似度のしきい値です。例: 職業が"Software Engineer"と80%以上類似)。### NFCが実行されなかった理由で分岐する`NFC`ノードの後では、`nfc.skip_reason`を`equals`または`in`と組み合わせて使い、チップの読み取りが行われなかった理由に応じてセッションをルーティングします。このフィールドは次の7つの固定値を取ります:- `USER_SKIPPED`
- `DOCUMENT_WITHOUT_CHIP`
- `CHIP_CERTIFICATE_UNAVAILABLE`
- `DEVICE_WITHOUT_NFC`
- `INTEGRATION_WITHOUT_NFC_ACCESS`
- `MRZ_KEY_UNAVAILABLE`
- `JPKI_UNAVAILABLE`各値の意味は[NFCのスキップ理由](https://docs.didit.me/ja/core-technology/nfc-verification/warnings-nfc-verification.md#スキップ理由)を参照してください。NFCが成功した場合、`nfc.skip_reason`は`null`になるため、スキップ理由に対する`equals`ルールも`in`ルールも一致しません。このフィールドは、**ゲートによってスキップされた**NFCノードでも値が決まります。これには、NFCのレポートや警告が存在しない場合や、`allow_nfc_skip`が`false`であっても書類またはデバイスのゲートによってNFCが実行されない場合が含まれます。そのため、`nfc_verifications[]`のエントリに頼らずにこれらのセッションをルーティングできます。> [!NOTE]
>
> NFC対応状況が3値になる前に保存されたセッションでは、`has_device_nfc_support: false`となっている場合があります。そのため、古いWebセッションでは`INTEGRATION_WITHOUT_NFC_ACCESS`ではなく`DEVICE_WITHOUT_NFC`として値が決まることがあります。このグラフでは、ユーザーによるスキップに`equals`を、ゲートまたは対応状況によるスキップに`in`を使い、NFCが成功した場合には明示的なelseを使用しています。分岐は`NFC`ノードの後に置かれ、すべての遷移先は前方の終端ノードを指しています:```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" }
  }
}
```「既知のいずれかの理由でNFCが実行されなかった」ことを表すには、**7つすべて**の値を指定して`in`を使用します。NFCが成功した場合(`nfc.skip_reason: null`)や、グラフがまだ認識していない将来の値に備えて、明示的なelse分岐を残しておいてください。### Document AI(例: 資金証明)`DOCUMENT_AI`機能ノードは、1つ以上の書類をリクエストし、名前付きフィールドを抽出します:```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"
}
```設定した各フィールドは分岐に使える値`document_ai.<key>`となり、ステップの結果は`document_ai.status`になります。書類の名義人の氏名を保持するフィールドには`"is_full_name": true`を設定します。抽出された値は検証済みの本人の氏名(OCR/本人確認で得た氏名、またはセッションの期待される詳細情報)と照合され、`document_ai_name_match_score_threshold`を下回る不一致が生じた場合の処理は`document_ai_name_mismatch_action`で決まります。このフラグは**任意**で、どのフィールドにも設定しない書類があっても構いません。また、設定できるのは**書類1件につき最大1つのフィールド**のみです。Document AIのすべての設定フィールドについては、[ワークフロー機能の設定 → Document AI](https://docs.didit.me/ja/management-api/workflows/feature-configs.md#document-ai)を参照してください。### エンドポイントとドラフトのライフサイクルグラフの編集はアプリケーションごとに行い、コンソール/管理用エンドポイント(user-Bearerと`read:workflows`/`write:workflows`)を使用します。グラフを編集できるのは**ドラフト**バージョンのみのため、ライフサイクルは**ドラフト作成 → グラフ設定 → 公開**となります:| メソッド | パス | 用途 |
| - | - | - |
| `GET` | `…/verification-settings/{settings_uuid}/workflow-graph/` | 現在のグラフと`status`/`is_editable` |
| `POST` | `…/application/{app}/workflow-graph/validate/` (ボディ`{ "graph": … }`) | ドライランでの検証 |
| `GET` | `…/application/{app}/workflow-graph/field-definitions/` | 分岐に使用できるフィールドと有効な演算子 |
| `POST` | `…/verification-settings/{settings_uuid}/create-draft/` | 公開済みバージョンから編集可能なドラフトを作成 |
| `PUT` | `…/verification-settings/{settings_uuid}/workflow-graph/` (ボディ`{ "graph": … }`) | グラフを保存 |
| `PATCH` | `…/verification-settings/{settings_uuid}/` (ボディ`{ "status": "published" }`) | ドラフトを公開 |#### 検証の警告検証エンドポイントは`{ "is_valid": true, "graph": …, "warnings": [] }`を返します。警告は**参考情報**です。グラフは有効であり、警告があっても保存も公開もできます。各エントリには対象となる分岐ノードとアームが含まれるため、ビルダーは該当する条件を正確に示すことができます。```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` | 意味 |
| - | - |
| `branch_outcome_contradiction` | アームの条件と、そこから続くすべてのパスが到達する結果が矛盾しています。たとえば、`kyc.status NOT EQUALS Declined`が`Declined`の結果にルーティングされている場合です。結果はパスの数ステップ先にある場合もあります。 |
| `branch_condition_unreachable` | このアームは決して一致しません。この分岐に到達するすべてのパスで、そのステータスフィールドが条件で除外される値にすでに限定されているためです。 |
| `else_branch_unreachable` | elseアームは決して実行されません。他のアームが、この時点でフィールドが取り得るすべての値をすでにカバーしています。 |無効なグラフは`400`を返し、`errors`**および**ベストエフォートの`warnings`リストを含みます。保存をブロックするのは`errors`のみです。### 実践例: ソフトウェアエンジニアを資金証明にルーティングする> 本人確認の後、結果が**却下**であればセッションを却下します。保有者の**職業 ≈ "Software Engineer"**(類似度≥80%)であれば、**資金証明**書類をリクエストします。その後、最終判定を行います。```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" }
  }
}
```最終ノードでは`session_status: "Determine"`を使用します。これはセッションで実際に実行された機能に基づいて**自動的に判定**(承認、却下、レビュー中)します。そのため、どの分岐も`document_ai.status`(Document AIをスキップするパスには存在しません)を読み取ることなく、資金証明のパスとelseのパスの両方が正しく判定されます。分岐が読み取れるのは、その分岐に到達する*すべての*パスで機能が実行されたフィールドのみである点に注意してください。これを`{ "graph": <above> }`として`…/workflow-graph/`エンドポイントに送信します(先に検証してください)。**新規**ワークフローを一から作成するにはMCPの`didit_workflow_set_graph`を使用し、**既存の**ワークフローを変更するには`didit_workflow_edit_graph`を使用します(小規模な操作で、既存のノードと許可リストを保持します)。[Didit MCP](https://docs.didit.me/ja/integration/mcp/tools.md)を参照してください。


## OpenAPI

````yaml ja/openapi-25.json POST /v3/workflows/
openapi: 3.0.0
info:
  version: 3.0.0
  title: Didit Verification API
  description: 本人確認API。x-api-keyヘッダーで認証します。
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/workflows/:
    post:
      tags:
        - Workflows
      summary: ワークフローを作成
      description: >-
        シンプルなワークフローを作成します。`features`は実行順に送信してください（順序のルールが適用されます）。デフォルトは`published`のv1です。本文には`SimpleWorkflowRequest`に記載されたフィールドのみ指定できます。それ以外のキー（`workflow_type`を含む）は400で拒否されます。冪等ではなく、呼び出すたびに新しいワークフローが作成されます。1アプリケーションあたりの上限は50ワークフローです。
      operationId: create_workflow
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SimpleWorkflowRequest'
            examples:
              Simple KYC:
                summary: 本人確認、ライブネス検知、顔照合のリニアワークフロー
                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: 本人確認後にAMLを実行
                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: 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: >-
            ワークフローが作成されました。レスポンスボディは簡易的な一覧項目ではなく、ワークフローの完全な設定です。これは`GET
            /v3/workflows/{settings_uuid}/`が返すものと同じ、生の`VerificationSettings`のシリアライズ結果（約190フィールド:
            すべての機能のオン・オフ、しきい値、アクション、生成された`workflow_graph`）です。後続のセッション作成呼び出しで参照できるよう、`uuid`（`workflow_id`としても公開）を保存してください。注意:
            `features`は`" + "`で連結された文字列で、料金はJSONの数値です。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkflowDetail'
              examples:
                Created (abbreviated):
                  summary: 完全な設定オブジェクトの主要フィールド
                  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: >-
            バリデーションエラー。よくある原因：受け付け可能なホワイトリストにないトップレベルキー（例：`workflow_type`）、不明な`feature`の値、依存先より前に配置された機能（例：`OCR`より前の`FACE_MATCH`）、最初のステップとして使用されたパッシブ機能（`AML`、`IP_ANALYSIS`、`DATABASE_VALIDATION`、`KYB_KEY_PEOPLE`）、`config.questionnaire_uuid`がこのアプリケーションに存在しない`QUESTIONNAIRE`機能、署名する書類がないまま本番稼働することになる`SIGNATURE`機能、Advanced
            (AES)が利用できない状態で`signature_level:
            "aes"`を指定した`SIGNATURE`機能（`aes_not_available`。ワークフローの`signature_availability`を参照）、または範囲外のしきい値。ボディはDRFのバリデーションエラーオブジェクトで、キーはフィールド名、値は人が読めるメッセージの配列です。
          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: >-
            APIキーがない、形式が不正、期限切れ、または別のアプリケーションにスコープされています。[Auth
            API](/ja/auth-api/get-credentials)で更新し、再試行してください。
          content:
            application/json:
              examples:
                Invalid token:
                  value:
                    detail: You do not have permission to perform this action.
        '415':
          description: >-
            サポートされていないメディアタイプです。`Content-Type:
            application/json`を設定し、JSONボディを送信してください。
        '429':
          description: レート制限を超過しました。指数バックオフで再試行してください。
        '500':
          description: ワークフローの作成中に予期しないサーバーエラーが発生しました。安全に再試行できます。
      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: >-
        シンプルな直線型ワークフローを作成します。APIはこの機能リストを内部でノードベースのワークフローグラフに変換します。フィールドは厳格なホワイトリスト方式です。ここに記載されていないキー（`workflow_type`を含む）は400で拒否されます。
      required:
        - features
      properties:
        workflow_label:
          type: string
          maxLength: 50
          default: ID Verification
          description: >-
            ワークフローの表示名です（最大50文字）。省略した場合のデフォルトは`"ID
            Verification"`です。ワークフローを区別できるよう、必ず設定してください。
          example: Standard KYC
        is_default:
          type: boolean
          description: このワークフローを新しいセッションのデフォルトに設定します。
        status:
          type: string
          enum:
            - draft
            - published
          description: >-
            このフィールドを省略すると、セッションですぐに使える公開済みのワークフローが作成されます。公開せずに保存したい場合にのみ`draft`を使用してください。
        features:
          type: array
          minItems: 1
          description: 実行順に並べた認証機能。APIは各項目を次の項目にリンクし、最後のステータスノードを1つ自動的に追加します。
          items:
            $ref: '#/components/schemas/SimpleWorkflowFeature'
        is_white_label_enabled:
          type: boolean
          description: このワークフローで作成されたセッションのホワイトラベルカスタマイズを有効にします。
          default: false
        is_desktop_allowed:
          type: boolean
          description: デスクトップブラウザでの認証フローの実行を許可します。
          default: false
        max_retry_attempts:
          type: integer
          minimum: 0
          maximum: 10
          default: 3
          description: 認証が却下された後に許可される最大再試行回数です。`0`の場合、最初の却下でユーザーはブロックされます。
        retry_window_days:
          type: integer
          minimum: 1
          maximum: 365
          nullable: true
          default: 7
          description: 再試行回数のカウントに使用する日単位のローリングウィンドウ。`null`の場合は期間無制限の上限が適用されます。
        face_liveness_max_attempts:
          type: integer
          minimum: 1
          maximum: 3
          default: 3
          description: >-
            セッション1件あたりのライブネス検知の最大送信回数です。デフォルトは3で、初回の試行1回と再試行2回です。機能レベルの設定で上書きされない限り、この値は生成されるライブネス検知および年齢推定のワークフローノードにもコピーされます。
        face_match_max_attempts:
          type: integer
          minimum: 1
          maximum: 3
          default: 3
          description: >-
            セッション1件あたりの顔照合の最大送信回数です。デフォルトは3で、初回の試行1回と再試行2回です。機能レベルの設定で上書きされない限り、この値は生成される顔照合のワークフローノードにもコピーされます。
        session_expiration_time:
          type: integer
          minimum: 3600
          maximum: 2419200
          default: 604800
          description: 未完了のセッションが期限切れになるまでの秒数。最小1時間（3600）、最大4週間（2419200）。
    WorkflowDetail:
      type: object
      description: >-
        以下のフィールドには型が定義されています。このオブジェクトには、ワークフロー設定のその他すべての列（機能の切り替え、しきい値、警告アクション、許可される書類、コールバック）も追加プロパティとして含まれます。`workflow_type`に該当しないフィールドは`null`です。
      properties:
        uuid:
          type: string
          format: uuid
          description: バージョンごとの識別子（`settings_uuid`）です。ワークフローの各バージョンがそれぞれ固有の値を持ちます。
        workflow_id:
          type: string
          format: uuid
          description: ワークフローのすべてのバージョンで共有される不変の識別子。これを使って作成したセッションでは、公開済みの最新バージョンが使用されます。
        workflow_label:
          type: string
          description: ワークフローの表示名。
        workflow_type:
          type: string
          nullable: true
          enum:
            - kyc
            - kyb
            - adaptive_age_verification
            - biometric_authentication
            - address_verification
            - questionnaire_verification
            - email_verification
            - phone_verification
            - null
          description: ワークフローテンプレート。テンプレートなしで作成されたグラフワークフローでは`null`です。
        is_default:
          type: boolean
          description: アプリケーションのデフォルトのワークフローかどうか。
        is_archived:
          type: boolean
          description: アーカイブ済みのワークフローでは新しいセッションを開始できません。
        version:
          type: integer
          description: ワークフロー内のバージョン番号。
        status:
          type: string
          enum:
            - draft
            - published
          description: ドラフトバージョンは編集できます。公開済みバージョンは変更できず、新しいセッションで使用されます。
        published_at:
          type: string
          format: date-time
          nullable: true
          description: このバージョンが公開された日時。下書きの場合は`null`です。
        is_simple_workflow:
          type: boolean
          description: ワークフローにカスタムの`workflow_graph`がない場合は`true`です。
        is_editable:
          type: boolean
          description: '`draft`バージョンの場合のみ`true`です。'
        workflow_url:
          type: string
          format: uri
          description: このワークフローでセッションを開始する公開URLです。
        workflow_graph:
          type: object
          nullable: true
          additionalProperties: true
          description: ワークフローのグラフ構造(ノードとエッジ)。シンプルなワークフローでは`null`です。
        features:
          type: string
          description: '有効な機能を`" + "`で連結したものです。例: `"OCR + LIVENESS"`。'
        total_price:
          type: number
          nullable: true
          description: セッション1件あたりの料金。グラフ型ワークフローでは最も高い経路の料金です。
        min_price:
          type: number
          nullable: true
          description: ワークフロー内で最も安い経路の料金。
        max_price:
          type: number
          nullable: true
          description: ワークフロー内で最も高い経路の料金。
        special_add_on_prices:
          type: object
          nullable: true
          additionalProperties: true
          description: 組織固有のアドオン料金です。設定されていない場合は`null`です。
        max_retry_attempts:
          type: integer
          description: 認証が却下された後に許可される再試行回数。
        retry_window_days:
          type: integer
          nullable: true
          description: 再試行が許可される日数。
        session_expiration_time:
          type: integer
          description: 未完了のセッションが期限切れになるまでの秒数。
        questionnaire:
          type: object
          nullable: true
          additionalProperties: true
          description: ワークフローに紐づくアンケート、または`null`です。
        kyb_role_settings:
          type: array
          items:
            type: object
            additionalProperties: true
          description: KYBの主要人物に対する役割ごとの検証設定です。
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        signature_availability:
          type: object
          description: >-
            現在署名に使用できる電子署名のレベル。`signature_level`を設定する前に確認してください。`kyc`、`kyb`、グラフワークフローで返されます。
          properties:
            simple:
              type: boolean
              description: Simpleは常に利用できます。
            aes:
              type: boolean
              description: >-
                Advanced（AES）で現在署名できるかどうかです。`false`の間は、`signature_level:
                "aes"`の新しいステップを保存しようとすると`aes_not_available`で拒否されます。
            qes:
              type: boolean
              description: Qualified（QES）で現在署名できるかどうかです。適格プロバイダーが接続されるまでは`false`です。
        is_bank_verification_enabled:
          type: boolean
          description: >-
            シンプルなKYCまたはKYBワークフローで銀行認証を実行するかどうかです。連絡先ステップ（および位置情報認証）の後、データベース検証、AML、IP分析の前に実行されます。銀行認証はまだ一般提供されていません。有効化されていない場合、オンにしようとしても拒否されます。
        bank_verification_config:
          type: object
          additionalProperties: true
          description: >-
            シンプルなワークフローの銀行口座認証設定です。`BANK_VERIFICATION`ノードと同じキー（例:
            `bank_countries`、`bank_method_order`）を受け付けます。不明なキーは破棄されます。すべてのキーは任意で、指定しないキーはデフォルト値のままとなるため、`{}`はすべてデフォルト値であることを意味します。詳細は[銀行口座認証の設定](/ja/management-api/workflows/feature-configs#銀行口座認証)を参照してください。
          example: {}
        is_geolocation_enabled:
          type: boolean
          description: >-
            シンプルなKYCワークフローで位置情報認証を実行するかどうかです。連絡先ステップの後、銀行認証とデータベース検証の前に実行されます。企業（KYB）ワークフローでは実行できません。
        geolocation_config:
          type: object
          additionalProperties: true
          description: >-
            シンプルなワークフローの位置情報検証設定で、`GEOLOCATION`ノードと同じキー（例:
            `is_geolocation_geofencing_enabled`や`geolocation_max_attempts`）を受け付けます。不明なキーは破棄されます。すべてのキーは任意で、指定しないキーはデフォルト値のままとなるため、`{}`はすべてデフォルト値を意味します。
          example: {}
      additionalProperties: true
    SimpleWorkflowFeature:
      type: object
      required:
        - feature
      properties:
        feature:
          type: string
          description: 実行する機能。ここに示す大文字の値を使用してください。
          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: >-
            機能固有の設定です。`QUESTIONNAIRE`では、アンケート作成エンドポイントが返す`questionnaire_id`を`questionnaire_uuid`に指定します。`SIGNATURE`では、本番公開するワークフローに署名対象の書類が必要です。各セッションが独自の書類を持ち込めるよう`signature_documents_source`を`session`または`both`に設定するか、`status:
            "draft"`を送信して公開前に書類を追加してください。ワークフローの`signature_availability.aes`が`false`の間は、`signature_level:
            "aes"`は`aes_not_available`で拒否されます。`OCR`では、`methods`で各国が利用できる本人確認の方式（書類撮影、政府機関などの信頼できる情報源に対する書類不要の照会、デジタルIDウォレット）を選択します。省略すると、すべての国で書類撮影のみとなります。`SIGNATURE`については[電子署名の設定](/ja/management-api/workflows/feature-configs#電子署名)を参照してください。`signature_level`は現時点で`simple`（デフォルト。本人確認、メールアドレス、電話番号のいずれも不要）と`aes`を受け付けます。ワークフローの書類とそのフィールドはコンソールで管理されるため、APIでは`signature_documents_source:
            "session"`を指定してセッションごとに書類とフィールドを送信してください。
          additionalProperties: true
        label:
          type: string
          description: このワークフローノードの任意の内部ラベルです。
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        お客様のアプリケーションのAPIキーです。Business ConsoleのDevelopers -> API
        keysで取得できます。プライマリキーはフルアクセス権を持ちます。名前付きキーにはスコープを設定できます。リソースごとのアクセス権（なし、読み取り、書き込み）、一部のワークフローまたは承認済みセッションへの限定、IPアドレスのリストへの限定、有効期限の設定です。401は、キーが誤っている、失効している、または期限切れであることを意味します。403は、キーが送信されていない、キーにこのリソースやアクションへのアクセス権がない、またはIPリスト外のアドレスからリクエストが送信されたことを意味します。セッションのルートでの404は、セッションがキーのワークフローまたはステータスの対象外であることを意味します。メディアへのアクセス権がないキーでは、画像、動画、PDFのURLがnullで返されます。セッションの書き込み権限がないキーでは、セッションのリンクとトークンがnullで返されます。詳細は次を参照してください:
        https://docs.didit.me/console/api-keys

````

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