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

# Update Workflow

> Update a workflow. Versioning depends on the `status` field you send and the current state of the version: (1) no `status` on a **published** version → the published version is updated in place (same `uuid`, same `version`); (2) no `status` on a **draft** → the draft is updated and immediately published; (3) `status: "published"` on a **published** version → a NEW published version is created under the same `workflow_id` (new `uuid`, `version` + 1) and returned, and any existing draft in the group is deleted; (4) `status: "draft"` keeps a draft as a draft (autosave) but is rejected with 400 on a published version (`"Cannot revert a published version to draft."`). The body accepts the same strict field whitelist as create — unknown keys are rejected with 400.

export const AgentPromptAccordion = ({prompt, title = "AI Agent Integration Prompt"}) => {
  const [copied, setCopied] = React.useState(false);
  const handleCopy = e => {
    e.stopPropagation();
    if (!prompt) return;
    navigator.clipboard.writeText(prompt.trim()).then(() => {
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    });
  };
  const agents = ["Claude Code", "Codex", "Cursor", "Devin", "Windsurf", "GitHub Copilot"];
  return <div className="didit-agent-card">
      {}
      <div className="didit-agent-titlebar">
        <div className="didit-agent-dots" aria-hidden="true">
          <span className="didit-agent-dot didit-agent-dot-red"></span>
          <span className="didit-agent-dot didit-agent-dot-yellow"></span>
          <span className="didit-agent-dot didit-agent-dot-green"></span>
        </div>
        <span className="didit-agent-filename">{title}</span>
        <button type="button" className={`didit-agent-copy ${copied ? "didit-agent-copy-copied" : ""}`} onClick={handleCopy} title="Copy prompt to clipboard" aria-label={copied ? "Copied!" : "Copy prompt to clipboard"}>
          {copied ? <>
              <svg width="13" height="13" viewBox="0 0 16 16" fill="none">
                <path d="M3 8.5l3.5 3.5L13 4" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
              </svg>
              <span>Copied</span>
            </> : <>
              <svg width="13" height="13" viewBox="0 0 16 16" fill="none">
                <rect x="5" y="5" width="9" height="9" rx="1.5" stroke="currentColor" strokeWidth="1.5" />
                <path d="M11 5V3.5A1.5 1.5 0 0 0 9.5 2h-6A1.5 1.5 0 0 0 2 3.5v6A1.5 1.5 0 0 0 3.5 11H5" stroke="currentColor" strokeWidth="1.5" />
              </svg>
              <span>Copy</span>
            </>}
        </button>
      </div>

      {}
      <pre className="didit-agent-body"><code>{prompt.trim()}</code></pre>

      {}
      <div className="didit-agent-footer">
        <span className="didit-agent-footer-label">Paste into</span>
        <div className="didit-agent-chips">
          {agents.map(name => <span key={name} className="didit-agent-chip">{name}</span>)}
        </div>
      </div>
    </div>;
};

<AgentPromptAccordion
  title="Update Workflow API Prompt"
  prompt={`Update a simple Didit workflow through the Management API.

Endpoint:
PATCH https://verification.didit.me/v3/workflows/{settings_uuid}/

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

Requirements:
- Use PATCH and include only the fields I want to change.
- To rename the workflow, send workflow_label only.
- To change workflow checks, send the full desired features array. This replaces the previous feature order and config.
- Do not send workflow_graph, branches, actions, webhooks, or conditional logic.
- Send features in the exact execution order.
- 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.
- Keep dependency order valid. For example, put OCR before FACE_MATCH.
- If the workflow includes QUESTIONNAIRE, use the latest questionnaire_id as config.questionnaire_uuid.

Example metadata update body:
{
"workflow_label": "Premium KYC"
}

Example full feature replacement body:
{
"features": [
{
  "feature": "OCR",
  "config": {
    "documents_allowed": {
      "USA": {
        "DL": {
          "enabled": 1,
          "sides": 2
        }
      }
    }
  }
},
{
  "feature": "AML",
  "config": {
    "aml_score_review_threshold": 70,
    "aml_score_approve_threshold": 30
  }
}
]
}

Build the API call, handle validation errors, and return the updated workflow response.`}
/>

Use `PATCH` for partial updates. To rename a workflow, send only `workflow_label`.

```json theme={null}
{
  "workflow_label": "Premium KYC"
}
```

To change the checks in the workflow, send the full desired `features` array. This replaces the previous feature order and configuration.

```json theme={null}
{
  "features": [
    {
      "feature": "OCR",
      "config": {
        "documents_allowed": {
          "USA": {
            "DL": {
              "enabled": 1,
              "sides": 2
            }
          }
        }
      }
    },
    {
      "feature": "AML",
      "config": {
        "aml_score_review_threshold": 70,
        "aml_score_approve_threshold": 30
      }
    }
  ]
}
```

The v3 API keeps workflows simple: one linear path and one final status step. Branching, action nodes, and webhook nodes are not accepted here.

## Feature config reference

When you send `features` in a `PATCH`, the array replaces the previous feature order and configuration. Include every required config again.

The exact `config` object depends on the feature. Review the full field list, defaults, required settings, value ranges, and examples in [Workflow Feature Configs](/management-api/workflows/feature-configs).

For `OCR`, omit `config.documents_allowed`, send `null`, or send `{}` to allow every supported document type. Include it only when you want to restrict the workflow to specific countries or document types. For `QUESTIONNAIRE`, `config.questionnaire_uuid` is required.

## Updating workflow settings

You can patch session-level settings without touching the feature list. Send only the fields you want to change.

| Field                     | Type                      | Description                                                                                                |
| ------------------------- | ------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `is_white_label_enabled`  | boolean                   | Enable white-label customization for sessions created with this workflow.                                  |
| `is_desktop_allowed`      | boolean                   | Allow the verification flow to run on desktop browsers.                                                    |
| `max_retry_attempts`      | integer (0–10)            | Maximum retry attempts allowed after a declined verification. `0` blocks the user after the first decline. |
| `retry_window_days`       | integer (1–365) or `null` | Rolling window in days used to count retries (`null` = all-time limit).                                    |
| `session_expiration_time` | integer (3600–2419200)    | Seconds before an unfinished session expires. Minimum 1 hour, maximum 4 weeks.                             |

```json theme={null}
{
  "is_white_label_enabled": true,
  "is_desktop_allowed": true,
  "max_retry_attempts": 5,
  "retry_window_days": 14,
  "session_expiration_time": 86400
}
```

Use the workflow `uuid` returned by the list, create, or get endpoint as `settings_uuid` in this URL.


## OpenAPI

````yaml PATCH /v3/workflows/{settings_uuid}/
openapi: 3.0.0
info:
  version: 3.0.0
  title: Didit Verification API
  description: Identity verification API. Authenticate with x-api-key header.
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/workflows/{settings_uuid}/:
    patch:
      tags:
        - Workflows
      summary: Update workflow
      description: >-
        Update a workflow. Versioning depends on the `status` field you send and
        the current state of the version: (1) no `status` on a **published**
        version → the published version is updated in place (same `uuid`, same
        `version`); (2) no `status` on a **draft** → the draft is updated and
        immediately published; (3) `status: "published"` on a **published**
        version → a NEW published version is created under the same
        `workflow_id` (new `uuid`, `version` + 1) and returned, and any existing
        draft in the group is deleted; (4) `status: "draft"` keeps a draft as a
        draft (autosave) but is rejected with 400 on a published version
        (`"Cannot revert a published version to draft."`). The body accepts the
        same strict field whitelist as create — unknown keys are rejected with
        400.
      operationId: update_workflow
      parameters:
        - name: settings_uuid
          in: path
          required: true
          schema:
            type: string
            format: uuid
          description: Per-version UUID of the workflow to update.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SimpleWorkflowUpdateRequest'
            examples:
              Replace features:
                summary: Send the full desired feature order
                value:
                  features:
                    - feature: OCR
                    - feature: AML
              Rename:
                summary: Rename a workflow
                value:
                  workflow_label: Premium KYC
              Set as default:
                summary: Make this workflow the application's default
                value:
                  is_default: true
              Update config:
                summary: Change feature configuration
                value:
                  features:
                    - feature: OCR
                    - feature: LIVENESS
                      config:
                        face_liveness_method: passive
              Publish a draft:
                summary: Promote a draft to published
                value:
                  status: published
      responses:
        '200':
          description: >-
            Workflow updated. The body is the FULL configuration of the
            resulting version (same raw `VerificationSettings` shape as `GET
            /v3/workflows/{settings_uuid}/`). When the update created a new
            version (`status: "published"` sent on a published row) the returned
            `uuid` and `version` differ from the ones you patched — use the
            returned `uuid` for subsequent calls.
          content:
            application/json:
              schema:
                type: object
                description: >-
                  Full workflow configuration (see `GET
                  /v3/workflows/{settings_uuid}/`).
                additionalProperties: true
        '400':
          description: >-
            Validation error — a top-level key outside the accepted whitelist,
            an unknown feature, invalid ordering, out-of-range threshold,
            referencing a non-existent questionnaire, or `status: "draft"` sent
            for a published version (`"Cannot revert a published version to
            draft."`). The response body is a DRF validation error keyed by
            field name.
        '403':
          description: API key missing or invalid.
          content:
            application/json:
              examples:
                Invalid token:
                  value:
                    detail: You do not have permission to perform this action.
        '404':
          description: >-
            No workflow with this `settings_uuid` exists for the authenticated
            application.
        '415':
          description: 'Unsupported media type. Set `Content-Type: application/json`.'
        '429':
          description: Rate limit exceeded. Retry with exponential backoff.
        '500':
          description: Unexpected server error. Safe to retry.
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: curl
          label: cURL
          source: >-
            curl -X PATCH
            'https://verification.didit.me/v3/workflows/a1b2c3d4-5678-90ab-cdef-111111111111/'
            \
              -H 'x-api-key: YOUR_API_KEY' \
              -H 'Content-Type: application/json' \
              -d '{"workflow_label": "Premium KYC"}'
        - lang: Python
          label: Python (requests)
          source: |-
            import requests

            resp = requests.patch(
                f"https://verification.didit.me/v3/workflows/{settings_uuid}/",
                headers={"x-api-key": "YOUR_API_KEY"},
                json={"workflow_label": "Premium KYC"},
                timeout=10,
            )
            resp.raise_for_status()
            print(resp.json()["workflow_label"])
        - lang: JavaScript
          label: Node.js (fetch)
          source: >-
            const res = await
            fetch(`https://verification.didit.me/v3/workflows/${settingsUuid}/`,
            {
              method: "PATCH",
              headers: {
                'x-api-key': 'YOUR_API_KEY',
                "Content-Type": "application/json",
              },
              body: JSON.stringify({ workflow_label: "Premium KYC" }),
            });

            if (!res.ok) throw new Error(`Didit ${res.status}`);

            const workflow = await res.json();

            console.log(workflow.workflow_label);
components:
  schemas:
    SimpleWorkflowUpdateRequest:
      type: object
      description: >-
        Update workflow metadata or replace the full linear feature list. STRICT
        field whitelist: any key not listed here is rejected with a 400.
      properties:
        workflow_label:
          type: string
          maxLength: 50
          description: Display name for the workflow (max 50 characters).
        is_default:
          type: boolean
          description: Set this workflow as the default for new sessions.
        status:
          type: string
          enum:
            - draft
            - published
          description: >-
            Controls versioning. Omit to update the current version in place
            (drafts auto-publish). `published` on an already-published version
            creates and returns a NEW version. `draft` is only valid while the
            version is still a draft.
        features:
          type: array
          minItems: 1
          description: If provided, this replaces the full feature order and configuration.
          items:
            $ref: '#/components/schemas/SimpleWorkflowFeature'
        is_white_label_enabled:
          type: boolean
          description: >-
            Enable white-label customization for sessions created with this
            workflow.
        is_desktop_allowed:
          type: boolean
          description: Allow the verification flow to run on desktop browsers.
        max_retry_attempts:
          type: integer
          minimum: 0
          maximum: 10
          description: >-
            Maximum retry attempts allowed after a declined verification. `0`
            blocks the user after the first decline.
        retry_window_days:
          type: integer
          minimum: 1
          maximum: 365
          nullable: true
          description: >-
            Rolling window in days used to count retries. `null` enforces an
            all-time limit.
        face_liveness_max_attempts:
          type: integer
          minimum: 1
          maximum: 3
          description: >-
            Maximum liveness submissions per session. This value is also copied
            into generated liveness and age-estimation workflow nodes unless the
            feature-level config overrides it.
        face_match_max_attempts:
          type: integer
          minimum: 1
          maximum: 3
          description: >-
            Maximum face-match submissions per session. This value is also
            copied into generated face-match workflow nodes unless the
            feature-level config overrides it.
        session_expiration_time:
          type: integer
          minimum: 3600
          maximum: 2419200
          description: >-
            Seconds before an unfinished session expires. Minimum 1 hour (3600),
            maximum 4 weeks (2419200).
    SimpleWorkflowFeature:
      type: object
      required:
        - feature
      properties:
        feature:
          type: string
          description: Feature to run. Use the uppercase values shown here.
          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
        config:
          type: object
          description: >-
            Feature-specific settings. For `QUESTIONNAIRE`, include
            `questionnaire_uuid` with the `questionnaire_id` returned by the
            questionnaire create endpoint.
          additionalProperties: true
        label:
          type: string
          description: Optional internal label for this workflow node.
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key

````