Core ConceptsConventions and objects

Conventions & Object Schemas - Deepvue Workflows API

Reference for Workflows API conventions and object shapes. Timestamps, the list envelope, absent versus null, and the Workflow, Run, Check, and ReviewFlag schemas.

Overview

This page is the reference for how the Workflows API shapes its JSON, and for every object you will read back from it.

Conventions

Timestamps

All timestamps are RFC 3339 UTC, for example 2026-07-30T09:14:02Z.

Absent means unset

Optional fields are omitted from the JSON rather than sent as null.

There are two exceptions. action_required and error are always present and are explicitly null when not applicable, so a poller can test them without a key-existence check.

On the run detail endpoint, decision and resolved_at follow the same rule: always present, a value or an explicit null.

The list envelope

Every list endpoint returns a fixed envelope.

{ "data": [ "..." ], "total": 128, "limit": 50, "offset": 0 }

total is the count of all records matching the filter, ignoring limit and offset.

Errors

Transport errors use {"error": "<message>"}, and add "code": "<CODE>" when a machine-readable discriminator is available.

Unknown fields are rejected

Unknown JSON fields in a request body are rejected, not silently ignored.

Object schemas

Workflow

The list shape, returned by GET /v1/workflows and POST /v1/workflows/{id}/webhook.

FieldTypePresenceNotes
idstring (uuid)alwaysUse this to trigger runs.
namestringalways
descriptionstringoptionalOmitted when unset.
publishedbooleanalwaystrue = a published version exists.
run_ttl_secondsintegeralwaysHow long a run stays usable from start. 0 = no deadline.
abandon_timeout_secondsintegeralwaysIdle window before ?status=abandoned reports a run. 0 = off.
lifecycle_webhook_urlstringoptionalOmitted when no per-workflow webhook is configured.
created_atstring (ts)always

WorkflowDetail

Returned by GET /v1/workflows/{id}. Everything in Workflow, plus steps, a Step[] that is always present and is [] when the workflow has none.

Step

FieldTypeNotes
keystringSame vocabulary as Check.key.
labelstringSame vocabulary as Check.label.

steps lets you build your result mapping before running anything: every key that can appear in a run's checks[] appears here.

It is a superset. Workflows branch, so one run may take a DigiLocker path and another a document-OCR path. Treat a key that never arrives as "that branch was not taken", not as an error.

Order is indicative, not guaranteed. It approximates the order a journey runs in, but the underlying graph has retry loops and alternate paths.

Only verification checks are listed. Consent screens, document capture, decision logic, and other interior steps are not, since they produce no result you receive. steps reflects the version a run would actually execute: the published version when one exists, otherwise the latest.

Run

FieldTypeListDetailNotes
idstring (uuid)
workflow_idstring (uuid)
reference_idstringEchoed from the trigger request.
statusenumSee Run status lifecycle.
started_atstring (ts)
completed_atstring (ts) or nullnull until terminal.
action_requiredActionRequired or nullNon-null only on a non-terminal status.
errorRunError or nullNon-null only when status is failed or expired.
checksCheck[]Detail only. Omitted when empty.
decisionenum or nullDetail only. review, approve, reject, or null.
notesstringoptionalWhat the reviewer typed. Omitted, never null, when they typed nothing.
resolved_atstring (ts) or nullnull until a verdict is recorded.
reviewsReviewFlag[]Detail only. Omitted when the run is flagged for nothing.

checks, reviews, and the three decision fields are deliberately absent from list responses. List to find runs, then GET /v1/runs/{id} to read results.

There is no reviewer field. Who ruled is not exposed on this API. The response tells you that a verdict was reached and when, not by whom.

ActionRequired

The run is parked waiting on a human. Present only on a non-terminal status.

A run can be waiting on either one of your operators or the end customer. Read type below, not status, to tell those apart.

FieldTypePresenceNotes
typeenumalwayscustomer_input - send the end user to url. review - an internal reviewer must decide.
signal_namestringalwaysPass to POST /v1/signals/{run_id}/{signal_name} to unblock.
urlstringwhen type is customer_inputSigned hosted-journey link. Omitted for review.

Check

One logical verification step. Stable across workflow edits, keyed by a published name and never by an internal node identifier.

FieldTypePresenceNotes
keystringalwaysStable machine name, for example pan, face_match, court.
labelstringalwaysHuman-readable, for example PAN verification.
statusenumalwayspending, running, passed, failed.
dataobjectwhen the step produced outputThe step's result fields. Shape varies per key.

Order is execution order, oldest first.

A step the workflow has not reached yet has no entry. Absence means "not started", not "failed".

Steps that run as a submit-then-poll pair appear as one entry whose data reflects the poll result. data field names are per-key, documented per check, and stable for a given key.

ReviewFlag

There is one decision per run. An operator looking at a finished run is deciding about the person, with the flags as evidence for that one call. So reviews[] records why a run was flagged, and decision records what was concluded.

FieldTypePresenceNotes
node_idstringalwaysWhich step. The same identifier ?view=report exposes.
labelstringalwaysThe step's name, for example Face Match.
reasonstringalwaysWhy it is flagged, for example The customer declined to provide this.

node_id is the one internal identifier on this shape, and it is deliberate. A partner told "this run wants a look" is also told which step, without opening a dashboard. It is the same identifier ?view=report exposes.

{
  "decision": "approve",
  "notes": "KYB docs verified manually",
  "resolved_at": "2026-08-12T11:08:56Z",
  "reviews": [
    { "node_id": "n_uan_confirm", "label": "Collect Text (single field)",
      "reason": "The customer declined to provide this." },
    { "node_id": "n_bureau_initiate", "label": "Credit report - consent & redirect",
      "reason": "The customer did not complete consent." }
  ]
}

reviews[] is identical on GET /v1/runs/{id} and ?view=report: same flags, same order, as are the decision fields. If a report card reads needs_review, that step is in reviews[]. The two cannot disagree. Both are absent from the rendered PDF.

RunError

Present only when status is failed or expired. See Errors for the code table and what to do about each one.

FieldTypePresenceNotes
codeenumalwaysSee Errors.
checkstringwhen attributablekey of the check the run exited on.
messagestringalwaysA plain sentence. Safe to log, not intended for end users.

Next steps