Skip to main content
PATCH
curl

What this does

A verification session is made up of individual features (steps): ID/OCR, Liveness, Face Match, AML, Proof of Address, Phone, and so on. This endpoint lets you set the status of one of those steps to Approved, Declined, or In Review. Use update-status when you want to approve, decline, or re-open the whole session. Use this endpoint when you only want to record a decision on a single step, for example to mark the Face Match step as Declined for your own review workflow. A session that already has a decision keeps it: only the step changes. If the session has no decision yet and its workflow is waiting on exactly this step, applying the override completes the step, as finishing it normally would. The workflow moves on, later steps run, and a status node can set the session decision and fire a status.updated webhook.

Targeting a step with node_id

In graph-based workflows each step has a node_id (for example feature_ocr_1, feature_liveness_1, feature_aml_1). You can find these in the session decision — each feature in a V3 decision carries its node_id. For non-graph (single-step) workflows the underlying feature has no node ID. Pass the literal value default as the nodeId to target it. Because no step of such a workflow has a node ID, also pass feature_type (for example LIVENESS, AML or FACE_MATCH) to say which step you mean. An unknown feature_type returns 400.

Wait until the person finishes the flow

By default the override applies at once. If the person is still going through the flow, that changes a step under a flow that is still running; the override is then recorded with forced: true. Set defer_until_flow_finishes: true to wait instead. While the session is Not Started, In Progress or Resubmitted and the person has not finished, the override is stored as pending_until_flow_finishes. It applies when the person finishes the flow, after the flow reaches its own decision. On a session whose flow already ended, it applies at once either way. A waiting override is cancelled instead of applied when:
  • the person redoes the step before finishing (check_changed),
  • a newer override on the same step replaces it (replaced),
  • the session leaves the flow unfinished: abandoned, expired, or decided mid-flow (session_closed),
  • you cancel it with Cancel Feature Override (cancelled_by_reviewer).
The response’s override tells you what happened: state is applied or pending_until_flow_finishes, and applied_at is set once it applied. The top-level new_status is the step’s stored status, so it stays unchanged while the override waits. Use List Feature Overrides to see every override of a session and whether the person is still in the flow.

KYC and KYB support

Works identically for User Verification (KYC) and Business Verification (KYB) sessions — Didit resolves the sessionId across both. Supported step types include ID/OCR, Liveness, Face Match, NFC, AML, Proof of Address, Phone, Email, Database Validation, Questionnaire, and the KYB registry / documents / key-people checks.
Standalone API sessions (those created through the standalone verification APIs, session_type = API) cannot have individual feature statuses changed — the endpoint returns 400.

Examples

What happens after an update

  • Webhook: a data.updated event fires when the override applies, at once or when the flow finishes. Nothing is sent while it waits or when it is cancelled.
  • Activity: every override is recorded in the session’s activity as FEATURE_OVERRIDE_PENDING, FEATURE_OVERRIDE_APPLIED or FEATURE_OVERRIDE_CANCELLED, with the actor (API key, user, or the system when a waiting override applies). The request’s entry carries your comment as its reason. In the reviews array of the session decision these entries appear with new_status: null, and the request’s entry has your reason in comment.
  • Session decision: a session that already has a decision keeps it. To change the final decision, call update-status separately.

Permission

Requires the write:sessions privilege, with either a client API key (x-api-key) or a user authorization header. A scoped API key needs write access to decisions.

Authorizations

x-api-key
string
header
required

Your application's API key, from Developers -> API keys in the Business Console. The primary key has full access. A named key can be scoped: none, read or write per resource, limited to some workflows or to approved sessions, to a list of IP addresses, and to an expiry date. 401 means the key is wrong, revoked or expired; 403 means no key was sent, the key has no access to this resource or action, or the request came from an address outside its IP list; 404 on a session route means the session is outside the key's workflows or statuses. A key without media access receives image, video and PDF URLs as null, and a key without sessions write receives session links and tokens as null. See https://docs.didit.me/console/api-keys.

Path Parameters

sessionId
string<uuid>
required

UUID of the verification session. Accepts both user (KYC) and business (KYB) session IDs — the service resolves the ID across both session types.

Example:

"11111111-2222-3333-4444-555555555555"

nodeId
string
required

Workflow graph node ID of the feature to update (for example feature_ocr_1). Use the literal value default for non-graph (single-step) workflows where the feature has no node ID.

Example:

"feature_ocr_1"

Body

application/json
new_status
enum<string>
required

Target status for this feature. Must differ from the current value.

Available options:
Approved,
Declined,
In Review
Example:

"Approved"

comment
string

Optional free-text note recorded on the session's review trail for this feature change.

Example:

"Document manually verified by compliance."

feature_type
enum<string>

Which kind of step to target. Needed on non-graph workflows (nodeId = default), where every step shares no node; optional otherwise. An unknown value returns 400.

Available options:
ID_VERIFICATION,
OCR,
OCR_BACK,
NFC,
LIVENESS,
FACE,
AGE_ESTIMATION,
AGE_VERIFICATION,
FACE_SEARCH,
FACE_MATCH,
IP_ANALYSIS,
AML,
PHONE,
PHONE_VERIFICATION,
EMAIL,
EMAIL_VERIFICATION,
POA,
PROOF_OF_ADDRESS,
DATABASE_VALIDATION,
DATA_VALIDATION,
QUESTIONNAIRE,
DOCUMENT_AI,
KYB_REGISTRY,
KYB_DOCUMENTS,
KYB_KEY_PEOPLE,
BANK_VERIFICATION,
GEOLOCATION
Example:

"LIVENESS"

defer_until_flow_finishes
boolean
default:false

While the person is still in the flow, store the override as pending_until_flow_finishes and apply it when the flow finishes, instead of at once. Omitted or false, the override applies at once. On a session whose flow already ended it applies at once either way.

Example:

false

Response

The override was recorded. new_status is the check's status as stored: the requested one once the override applied, the unchanged one while it waits for the flow to finish. override says which happened.

session_id
string<uuid>
required
node_id
string | null
required

The updated step's workflow node, or null for a step without a node (the default path in a non-graph workflow).

Example:

"feature_ocr_1"

feature_type
string
required

Model name of the updated feature (e.g. KYC, Face, FaceMatch, AML, POA).

Example:

"KYC"

new_status
string
required

The check's stored status: the requested one once the override applied, the unchanged one while the override waits for the flow to finish.

Example:

"Approved"

override
object
required

One override of a check (feature) status made with PATCH /v3/session/{sessionId}/features/{nodeId}/update-status/: what it changes, whether it applied or still waits for the person to finish the flow, who asked and why.

Last modified on November 1, 2026