Skip to main content
Use these config fields inside each item of the features array for POST /v3/workflows/ and PATCH /v3/workflows/{settings_uuid}/.
The v3 workflow API builds a linear node-based workflow from the ordered features array. Send features in the exact execution order.
Which engine runs a feature — Didit’s own, or a third-party provider — is not one of the config fields below. It’s managed through the console’s Marketplace, which sets provider_key and fallback_to_native on the feature’s config object for you.

Validation rules

  • OCR defaults to all supported countries and document types when config.documents_allowed is omitted, null, or {}. If you send a custom documents_allowed object, it must contain at least one valid country and one enabled document type. Each document config can set sides to 1 for front-only capture or 2 for front-and-back capture.
  • QUESTIONNAIRE requires config.questionnaire_uuid.
  • KYB_DOCUMENTS requires config.kyb_required_document_groups.
  • SIGNATURE refuses signature_level: "qes" with qes_not_available until qualified signatures are available, and a new step at signature_level: "aes" with aes_not_available while signature_availability.aes is false on the workflow. Its documents must exist when a session is created: with signature_documents_source set to workflow, the step needs documents uploaded in the console, and a step with none can stay a draft but cannot go live; with session, every create call must send sign.documents.
  • FACE_MATCH must come after OCR in simple workflow requests.
  • NFC and DATABASE_VALIDATION require OCR when they appear in the same workflow. AML needs one of OCR, KYB_REGISTRY, or DOCUMENT_AI before it; with only DOCUMENT_AI in front of it the screened full_name has to be fillable - either from an upstream Document AI field already keyed full_name, which is mapped for you, or from an explicit config.aml_field_sources entry (see AML).
  • KYB sub-features such as KYB_DOCUMENTS and KYB_KEY_PEOPLE require KYB_REGISTRY earlier in the workflow.
  • A workflow is either a person (KYC) workflow or a business (KYB) workflow, never both. A workflow that uses any KYB feature (KYB_REGISTRY, KYB_DOCUMENTS, KYB_KEY_PEOPLE) may only combine it with AML, DOCUMENT_AI, QUESTIONNAIRE, PHONE_VERIFICATION, EMAIL_VERIFICATION, IP_ANALYSIS, and SIGNATURE. It cannot include person-only features such as OCR, LIVENESS, FACE_MATCH, NFC, PROOF_OF_ADDRESS, DATABASE_VALIDATION, or AGE_ESTIMATION, and a person workflow cannot include KYB features. On a business workflow DOCUMENT_AI compares any field marked is_full_name against the verified company instead of a person. To verify the people behind a company, build a separate KYC workflow and reference it from the KYB_KEY_PEOPLE node using kyb_ubo_verification_workflow, kyb_officer_verification_workflow, or kyb_shareholder_verification_workflow.
  • Action fields use DECLINE, REVIEW, or NO_ACTION unless the field below says it is restricted.
  • Score and threshold fields are numbers from 0 to 100 unless a narrower range is listed.

Common status rules

Every feature supports an optional status_rules array. Use it to override the feature status when a field condition matches.
Read the example above as: kyc.extra_fields.profession fuzzy matches Soft. Engineer with a minimum score of 80 → set the feature status to Declined. For ID Verification, target extracted extra_fields values such as kyc.extra_fields.profession, driver license class validity dates like kyc.extra_fields.dl_class_code_b_from and kyc.extra_fields.dl_class_code_b_to, or per-class restriction/information codes like kyc.extra_fields.dl_class_code_b_notes (column 12 of UK licences). These values come from the OCR result’s extra_fields object; they are not part of expected_details.
dl_class_code_*_from and dl_class_code_*_to are always either a valid ISO date or absent from extra_fields — Didit never returns unreadable OCR text in a date field. If the class-table cell can’t be read, the field is omitted rather than sent as a raw string, so use the is_empty operator to route unreadable class dates instead of assuming the field is always present.
For date fields, use value_type: "relative_date" with a value object shaped as { "direction": "past" | "future", "amount": number, "unit": "days" | "months" | "years" }. For example, operator: "less_than" with { "direction": "past", "amount": 3, "unit": "years" } matches dates older than three years from today.

Compare against a specific step

A graph workflow can run the same feature more than once, for example three ID Verification steps. With value_type: "field", append @<node_id> to the value to read it from one specific step. The referenced node must be a feature step that always runs before the rule’s own step, on every path that reaches it, or the rule’s own step itself. A value without the suffix is read from the rule’s own step.
Read this rule, set on the third ID Verification step, as: this step’s kyc.full_name fuzzy matches the full name read by step ocr_1 with a minimum score of 80 → set the feature status to Declined. In the console, the variable picker lists each eligible step by its number on the canvas and stores the suffix for you.

OCR / ID Verification

Feature value: OCR.
Document liveness is configured with the six document_liveness_* thresholds above, not with per-signal action fields. portrait_replacement_action, printed_copy_action and screen_capture_action are account-level settings and are not accepted in a workflow feature config: the API strips unknown config keys on save, so sending them there has no effect. Each signal has a decline threshold and a review threshold on a 0-100 scale where a higher score means the document is more likely to be genuine.
Example:

Methods per country

methods is keyed by ISO 3166-1 alpha-3 country code. Each country carries up to three method objects; anything you leave out takes its default.
wallet.on_failure is fallback_to_document, decline or retry. retry (wallet only, document capture off for the country) keeps a user whose sign-in did not finish on the wallet step to try again; the session is never declined for it and stays open until they finish or it expires. The id_lookup switches take only fallback_to_document or decline. To keep documents out of the first screen and offer them only when a wallet or lookup does not land, set document.fallback_only. The example uses Finland, where the Finnish Trust Network comes first and document capture is the fallback. Finland also needs its document types enabled in documents_allowed (for example passport and ID card) so the fallback has documents to offer.
Both lookups above are available in today’s catalog, so that config saves as written. The wallet block is left out of this example on purpose: a wallet saves only in a country where the catalog marks it available, and wallet.enabled: true anywhere else is rejected and takes the whole save with it, lookup configuration included. Where the catalog marks a wallet available, add it to that country:
Validation the API applies on save:
  • An unknown country code, an unknown key inside a country, or an unknown key inside a method is rejected — nothing is silently dropped.
  • A country where no method is enabled is rejected: nobody there could verify.
  • A wallet or lookup can only fall back to document capture when document capture is enabled for that country. fallback_to_document in a country where document.enabled is false declines at runtime, because there is nowhere to fall back to.
  • document.fallback_only: true is rejected with HTTP 400 unless document.enabled is true and at least one wallet or ID lookup in that country falls back to document capture.
The current staging implementation applies id_lookup.response_fields to comparison output, optional gender and retained registry portraits. Required identity fields remain part of the verification record. This is not a guarantee that every intermediate provider payload is excluded from processing. Production rollout has not been verified for this change; confirm the behavior in your target environment before relying on field selection for retention requirements.
Read the capability catalog before you write methods — through the console’s Countries tab, or with the didit_workflow_get_id_verification_methods_catalog MCP tool. Behaviour, coverage and billing are on ID Verification methods.

NFC / ePassport

Feature value: NFC.

Liveness

Feature value: LIVENESS.

Face Match

Feature value: FACE_MATCH.

Age Estimation

Feature value: AGE_ESTIMATION.

Phone Verification

Feature value: PHONE_VERIFICATION. Phone Verification is disabled until the organization completes its first top-up.
Phone intelligence enrichment is an optional add-on. When phone_enrichment_enabled is true, each completed phone verification is enriched with phone intelligence and billed $0.05 per request in addition to the standard phone verification cost. The score-based actions only take effect once the enrichment score is available; the trust-index, phone-type and porting actions apply as soon as enrichment runs.The social footprint check is a second, separate add-on. When phone_social_enabled is true, each completed phone verification also reports which online platforms the number is registered on - messaging, social media, e-commerce and professional services - and is billed $0.05 per request. It can be enabled with or without phone_enrichment_enabled: the two add-ons are priced and billed independently. A lookup that finds the number on none of the platforms it covers is a valid, billable answer and triggers phone_no_social_presence_action. Use phone.social_profiles_registered (the number of platforms the number is registered on) to branch on the result in a workflow graph.

Email Verification

Feature value: EMAIL_VERIFICATION.
Email intelligence enrichment is an optional add-on. When email_enrichment_enabled is true, each completed email verification is enriched with email intelligence and billed $0.05 per request in addition to the standard email verification cost. The score-based action takes effect once the enrichment score is available; the breach actions apply as soon as enrichment runs.The social footprint check is a second, separate add-on. When email_social_enabled is true, each completed email verification also reports which online platforms the address is registered on - email providers, social media, professional, e-commerce and entertainment services - and is billed $0.05 per request. It can be enabled with or without email_enrichment_enabled: the two add-ons are priced and billed independently. A lookup that finds the address on none of the platforms it covers is a valid, billable answer and triggers email_no_social_presence_action. Use email.social_profiles_registered (the number of platforms the address is registered on) to branch on the result in a workflow graph.

Database Validation

Feature value: DATABASE_VALIDATION. Example:
database_validation_countries is what makes this step do anything. A DATABASE_VALIDATION feature saved without it is accepted and then runs no check at all, so always send at least one country with at least one service ID.
A service ID the step cannot run is rejected with a 400 that names it and says why, and nothing is saved. That covers an ID that is not in the catalog, an ID that belongs to another country, a service that is not available yet, and a service offered only through the standalone POST /v3/database-validation/. A service whose inputs no earlier step provides is rejected the same way, with the missing inputs listed. A service the saved workflow already carries but can no longer run is removed when you save it again. For example, this Argentina workflow reads the DNI number and gender from ID Verification and checks them against RENAPER without a selfie:
Use arg_renaper instead, after a LIVENESS step, to also match the selfie against the photo RENAPER holds. See RENAPER for its face match score and threshold.

Bank Verification

Feature value: BANK_VERIFICATION. The user verifies a bank account, and the account holder the bank reports is compared against the identity an earlier step in the workflow established. The user does it by one of two methods: bank sign-in (open_banking), where they sign in at their bank, or the account check (account_lookup), where they type the account details and the bank confirms the name on it. bank_method_order and each country’s methods choose which methods a country offers and which comes first; see Bank verification methods. The step produces evidence - a holder-name score, the comparison that produced it, reason codes - and the bank_*_action keys turn that evidence into a status. Two things decide whether the node does anything at all. bank_countries is a whitelist, so an empty map offers no bank and runs no check. And the holder needs something to be compared against: put an OCR, DATABASE_VALIDATION or QUESTIONNAIRE step in front of it, send expected_details on session creation, or map the fields yourself with bank_field_sources. With none of those, ownership can only be unknown, which is what bank_reference_identity_missing_action decides.
Bank Verification is still rolling out, so a BANK_VERIFICATION node is only accepted on an account where it has been enabled. Everywhere else the save is rejected and says so. Which route runs the step is not configured here either: it is the provider_key and fallback_to_native pair the console’s Marketplace sets for you.

Connecting an account

When the user cannot verify

The user can always continue without a bank, and the step never leaves them stuck. See When the person cannot verify their bank. What continuing means for the session is bank_unsupported_action, bank_attempts_exhausted_action or bank_skipped_action, depending on why the user continued, unless an attempt evaluated before it already decided the step: see Verdict actions.

Comparing the holder

Account check

These keys apply to the account check only. Bank sign-in keeps its close matches and its own bank_max_attempts.

Financial data

bank_expected_currencies works with the default ownership consent alone. The other three keys read real financial data, so each one needs the matching consent scope in bank_scopes and the save is refused without it.

What is stored

Verdict actions

Every key here takes DECLINE, REVIEW or NO_ACTION unless it is marked restricted, and falls back to the default below when you omit it or send null. Nothing that is not positive ownership evidence approves by default, and only demonstrable evidence against the user declines.

More controls

These keys are optional. Each action key takes DECLINE, REVIEW or NO_ACTION. Example config object, for an account where Bank Verification is enabled and the route you selected covers the country you list:
bank_countries is what makes this step do anything, and it is checked against the route the node runs on, not against a global list. A country where that route cannot establish account ownership is rejected on save and named in the error, so read the error rather than assuming the country was accepted and will be skipped at run time.

AML

Feature value: AML. For KYC person screening, use these fields: For KYB company screening, use these fields:

Screening an entity a Document AI step extracted

An AML step normally reads who it screens from the OCR step (a person) or the KYB_REGISTRY step (a company). A workflow whose only extraction step is DOCUMENT_AI - non-standardised documents such as a tax certificate or an incorporation deed - has neither, so it has to say where each screening input comes from. Example - screening the company named in a Mexican acta constitutiva, with no ID document anywhere in the workflow:
With no OCR and no KYB_REGISTRY step before it, an AML step must be able to fill full_name - there is no provider search without a name. A workflow that maps nothing, or maps a Document AI key no upstream step extracts, is rejected on save rather than saved and left screening nothing. AML precision follows directly from how many identifiers you supply: a name-only screening is what produces high false-positive volume.

Device & IP Analysis

Feature value: IP_ANALYSIS. Example:
Use recovered_device_action separately from duplicated_device_action when you want to monitor high-confidence recovered devices before automatically declining them. This is useful during rollout because recovered-device matches are designed for fraud-ring detection but should still be calibrated against your own traffic.

Location Verification

Feature value: GEOLOCATION. Checks where the person is while they verify, from the device position or from the connection’s IP location, against allowed and blocked areas, the IP location and the document address. See Location verification for how the step behaves and its report for the decision fields. Put it after ID Verification or Proof of Address if you want the distance to a document address, because the distance is only measured when an address is on file. With geolocation_position_source unset, the distance to the IP location needs a Device & IP Analysis step in the same workflow. Every key is optional: a step with an empty config asks the device for a position accurate to 250 m, no older than 120 seconds, gives the person 3 attempts and applies no area rule. Each finding has its own action key, and an action key you leave unset takes the default of the geolocation_preset you chose, or the per-key default listed below when you chose none. An uncertain or refused location defaults to REVIEW, never DECLINE, because a denied permission or a wide radius is not evidence of fraud. An action you set explicitly always wins over the preset. A replayed challenge (LOCATION_REPLAY_DETECTED) and a failed device attestation (LOCATION_INTEGRITY_FAILED) always decline and have no action key.

Area shapes

Each item of geolocation_areas has an id (1 to 64 characters of A-Z a-z 0-9 _ -, unique in the list), an optional label (up to 80 characters), a type of allowed or blocked, and a kind that picks the shape. A list holds at most 50 areas and needs at least one allowed area while is_geolocation_geofencing_enabled is true. geolocation_areas and geolocation_geofencing_by_country cannot be sent together, and geolocation_refusal_path: "end_session" needs geolocation_permission_denied_action to be REVIEW or DECLINE. The API refuses an area that could never match, such as a region of a country without published boundaries, instead of saving it. Example:

Proof of Address

Feature value: PROOF_OF_ADDRESS.

Questionnaire

Feature value: QUESTIONNAIRE.

KYB Registry

Feature value: KYB_REGISTRY. kyb_registry_fields_config maps each configurable field key to {"enabled": bool, "required": bool}. enabled: false hides the field, enabled: true, required: false shows it as optional, and enabled: true, required: true makes it mandatory at submit. company_name, country_code, and region are always shown and required and cannot be configured. When the object is omitted, null, or {}, the default applies: only incorporation_date is required and every other field is optional.
Configurable field keys: registration_number, incorporation_date, legal_address, vat_number, alternative_names, tax_number, company_type, legal_entity_identifier, location_of_registration, nature_of_business, registered_capital_amount, registered_capital_currency, website, email, phone, control_scheme. See configurable registry form fields for the end-user behavior and VAT and tax ID validation for how vat_number and tax_number are checked.

KYB Documents

Feature value: KYB_DOCUMENTS.

KYB Key People

Feature value: KYB_KEY_PEOPLE.

Document AI

Feature value: DOCUMENT_AI. Requests one or more documents from the user and extracts the named fields you define with a vision model. Each configured field becomes a branchable value document_ai.<key>, and the step’s outcome is document_ai.status. Each entry in document_ai_documents is a document: Each entry in a document’s fields is a field: Example:

E-signature

Feature value: SIGNATURE. Has the verified person, or a company’s key people, sign documents, at the Simple level (default) or Advanced (AES). Put it after the steps that verify the signer: ID Verification, and Email or Phone Verification for the code. See E-signature. Fields on a workflow document are placed in the console’s template editor. For session documents, send them in sign.documents[].fields, and send the values of api.<key> fields in sign.field_values. See Create session. Example, for documents sent with each session:
Last modified on November 6, 2026