Create Workflow Session
curl --request POST \
--url https://api.deepidv.com/v1/workflows/{workflow_id}/sessionsimport requests
url = "https://api.deepidv.com/v1/workflows/{workflow_id}/sessions"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://api.deepidv.com/v1/workflows/{workflow_id}/sessions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.deepidv.com/v1/workflows/{workflow_id}/sessions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.deepidv.com/v1/workflows/{workflow_id}/sessions"
req, _ := http.NewRequest("POST", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.deepidv.com/v1/workflows/{workflow_id}/sessions")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.deepidv.com/v1/workflows/{workflow_id}/sessions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_body{
"session_id": "80e801af-991b-425c-96fc-f5e07d794253",
"expires_at": null,
"steps": [
{
"step_id": "ID_VERIFICATION",
"status": "PENDING",
"requirements": {
"document": {
"require_front_only": false,
"front_only_document_types": ["passport"],
"require_secondary_id": false,
"require_tertiary_id": false,
"valid_id_types": [
"driver-license-us",
"driver-license-ca",
"passport-us",
"passport-ca",
"national-id-us"
],
"valid_states": ["NY", "CA", "ON", "BC"]
},
"face": {
"face_front_photo_only": true
}
}
},
{
"step_id": "FACE_LIVENESS",
"status": "PENDING",
"requirements": {
"challenge_type": "FaceMovementChallenge",
"confidence_threshold": 70
}
}
],
"current_step": 0
}
{
"error": "Invalid workflow step",
"invalid_steps": ["pep-sanctions"]
}
Workflow Runner
Create Workflow Session
Create a headless session that runs a workflow through the Workflow Runner API
POST
/
v1
/
workflows
/
{workflow_id}
/
sessions
Create Workflow Session
curl --request POST \
--url https://api.deepidv.com/v1/workflows/{workflow_id}/sessionsimport requests
url = "https://api.deepidv.com/v1/workflows/{workflow_id}/sessions"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://api.deepidv.com/v1/workflows/{workflow_id}/sessions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.deepidv.com/v1/workflows/{workflow_id}/sessions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.deepidv.com/v1/workflows/{workflow_id}/sessions"
req, _ := http.NewRequest("POST", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.deepidv.com/v1/workflows/{workflow_id}/sessions")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.deepidv.com/v1/workflows/{workflow_id}/sessions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_body{
"session_id": "80e801af-991b-425c-96fc-f5e07d794253",
"expires_at": null,
"steps": [
{
"step_id": "ID_VERIFICATION",
"status": "PENDING",
"requirements": {
"document": {
"require_front_only": false,
"front_only_document_types": ["passport"],
"require_secondary_id": false,
"require_tertiary_id": false,
"valid_id_types": [
"driver-license-us",
"driver-license-ca",
"passport-us",
"passport-ca",
"national-id-us"
],
"valid_states": ["NY", "CA", "ON", "BC"]
},
"face": {
"face_front_photo_only": true
}
}
},
{
"step_id": "FACE_LIVENESS",
"status": "PENDING",
"requirements": {
"challenge_type": "FaceMovementChallenge",
"confidence_threshold": 70
}
}
],
"current_step": 0
}
{
"error": "Invalid workflow step",
"invalid_steps": ["pep-sanctions"]
}
POST /v1/workflows/{workflow_id}/sessions
session_url — it’s designed for headless integrations (mobile/web SDKs) that drive the session directly through Submit Workflow Step.
Only workflows whose steps are all
ID_VERIFICATION and/or FACE_LIVENESS can be run through this API today. See Available steps below.Request
Headers
| Header | Required | Description |
|---|---|---|
x-api-key | Yes | Your organization’s API key |
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
workflow_id | string (uuid) | Yes | The ID of the workflow to run |
Body parameters
Both camelCase and snake_case parameter names are accepted. If both are provided for the same field, the camelCase value takes priority.| Parameter | Alias | Type | Required | Description |
|---|---|---|---|---|
email | — | string | Yes | Email address of the person completing the session |
first_name | firstName | string | Yes | First name of the person completing the session |
last_name | lastName | string | Yes | Last name of the person completing the session |
phone | — | string | Yes | Phone number in E.164 format, e.g. +14155552671 |
external_id | externalId | string | No | Your own identifier for this session, echoed back on retrieval |
expires_in_hours | expiresInHours | integer | No | Overrides the workflow’s default session expiry. 1-8760 |
Example request
curl -X POST https://api.deepidv.com/v1/workflows/29ce15d0-a1b7-4a66-b04e-8ade2b0c1ed0/sessions \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "jane.doe@example.com",
"first_name": "Jane",
"last_name": "Doe",
"phone": "+14155552671",
"external_id": "user_12345"
}'
const response = await fetch(
"https://api.deepidv.com/v1/workflows/29ce15d0-a1b7-4a66-b04e-8ade2b0c1ed0/sessions",
{
method: "POST",
headers: {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
email: "jane.doe@example.com",
first_name: "Jane",
last_name: "Doe",
phone: "+14155552671",
external_id: "user_12345",
}),
}
);
const session = await response.json();
import requests
response = requests.post(
"https://api.deepidv.com/v1/workflows/29ce15d0-a1b7-4a66-b04e-8ade2b0c1ed0/sessions",
headers={"x-api-key": "YOUR_API_KEY"},
json={
"email": "jane.doe@example.com",
"first_name": "Jane",
"last_name": "Doe",
"phone": "+14155552671",
"external_id": "user_12345",
},
)
session = response.json()
Response
200 — Success
| Field | Type | Description |
|---|---|---|
session_id | string (uuid) | The created session’s ID |
expires_at | string | null | ISO 8601 timestamp the session expires at, or null if it doesn’t expire |
steps | array | Ordered list of step objects, one per workflow step |
current_step | integer | 0-based index into steps of the step to submit next. Always 0 on creation |
steps[] object
| Field | Type | Description |
|---|---|---|
step_id | string | The step’s identifier. See Available steps |
status | string | PENDING, IN_PROGRESS, COMPLETED, FAILED, or SKIPPED. Always PENDING on creation |
requirements | object | Shape depends on step_id — see below |
Available steps
Only these two step types can be run through the Workflow Runner API. A workflow containing any other step type is rejected — see Error responses.step_id | Requirements shape |
|---|---|
ID_VERIFICATION | ID_VERIFICATION requirements |
FACE_LIVENESS | FACE_LIVENESS requirements |
ID_VERIFICATION requirements
| Field | Type | Description |
|---|---|---|
document.require_front_only | boolean | Always false at this point — no document_type has been chosen yet. Once the client selects a document type, check it against front_only_document_types before deciding whether to capture a back image |
document.front_only_document_types | string[] | Document types that never require a back-of-document image, e.g. ["passport"] |
document.require_secondary_id | boolean | Whether a second identity document must also be submitted |
document.require_tertiary_id | boolean | Whether a third identity document must also be submitted |
document.valid_id_types | string[] | Document types the step accepts, e.g. driver-license-us, passport-us |
document.valid_states | string[] | US states / Canadian provinces the step accepts for state-issued documents |
face.face_front_photo_only | boolean | Whether only a single front-facing selfie is required (vs. additional angles) |
FACE_LIVENESS requirements
| Field | Type | Description |
|---|---|---|
challenge_type | string | The liveness challenge method to run, e.g. FaceMovementChallenge |
confidence_threshold | number | Minimum liveness confidence score (0-100) required to pass |
Error responses
| Status | Description |
|---|---|
400 | Invalid request body, or the workflow contains a step type not supported by the Workflow Runner API (response includes invalid_steps), or the workflow is not active |
401 | Invalid or missing API key |
402 | Insufficient funds to run this workflow |
403 | The workflow belongs to a different organization |
404 | Organization or workflow not found |
429 | Too many requests |
{
"session_id": "80e801af-991b-425c-96fc-f5e07d794253",
"expires_at": null,
"steps": [
{
"step_id": "ID_VERIFICATION",
"status": "PENDING",
"requirements": {
"document": {
"require_front_only": false,
"front_only_document_types": ["passport"],
"require_secondary_id": false,
"require_tertiary_id": false,
"valid_id_types": [
"driver-license-us",
"driver-license-ca",
"passport-us",
"passport-ca",
"national-id-us"
],
"valid_states": ["NY", "CA", "ON", "BC"]
},
"face": {
"face_front_photo_only": true
}
}
},
{
"step_id": "FACE_LIVENESS",
"status": "PENDING",
"requirements": {
"challenge_type": "FaceMovementChallenge",
"confidence_threshold": 70
}
}
],
"current_step": 0
}
{
"error": "Invalid workflow step",
"invalid_steps": ["pep-sanctions"]
}