curl 'https://verification.didit.me/v3/sessions/delete/JOB_ID/' \
-H 'x-api-key: YOUR_API_KEY'import time
import requests
url = 'https://verification.didit.me/v3/sessions/delete/JOB_ID/'
while True:
job = requests.get(url, headers={'x-api-key': 'YOUR_API_KEY'}).json()
if job['status'] in ('COMPLETED', 'FAILED'):
break
time.sleep(3)
print(job['status'], job['outcomes'], job['error'])const url = 'https://verification.didit.me/v3/sessions/delete/JOB_ID/';
let job;
do {
await new Promise((r) => setTimeout(r, 3000));
job = await (await fetch(url, { headers: { 'x-api-key': 'YOUR_API_KEY' } })).json();
} while (job.status === 'PENDING' || job.status === 'PROCESSING');
console.log(job.status, job.outcomes, job.error);<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://verification.didit.me/v3/sessions/delete/{job_id}/",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-api-key: <api-key>"
],
]);
$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://verification.didit.me/v3/sessions/delete/{job_id}/"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-api-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://verification.didit.me/v3/sessions/delete/{job_id}/")
.header("x-api-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://verification.didit.me/v3/sessions/delete/{job_id}/")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-api-key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"job_id": "5b8f2c1e-7d3a-4f6b-9e2c-1a0d8f7e6c5b",
"status": "PROCESSING",
"total": 250,
"processed": 100,
"outcomes": {
"deleted": 82,
"none": 18,
"retained_with_user": 0,
"ineligible_no_vendor_user": 0,
"failed_retryable": 0,
"already_deleted": 0
},
"deleted_child_verifications": 0,
"error": null,
"created_at": "2026-10-09T10:15:00Z",
"completed_at": null
}Get Session Deletion Job
Poll the status and outcome counts of a bulk session deletion that Batch Delete Sessions answered with 202 because more than 20 sessions matched.
curl 'https://verification.didit.me/v3/sessions/delete/JOB_ID/' \
-H 'x-api-key: YOUR_API_KEY'import time
import requests
url = 'https://verification.didit.me/v3/sessions/delete/JOB_ID/'
while True:
job = requests.get(url, headers={'x-api-key': 'YOUR_API_KEY'}).json()
if job['status'] in ('COMPLETED', 'FAILED'):
break
time.sleep(3)
print(job['status'], job['outcomes'], job['error'])const url = 'https://verification.didit.me/v3/sessions/delete/JOB_ID/';
let job;
do {
await new Promise((r) => setTimeout(r, 3000));
job = await (await fetch(url, { headers: { 'x-api-key': 'YOUR_API_KEY' } })).json();
} while (job.status === 'PENDING' || job.status === 'PROCESSING');
console.log(job.status, job.outcomes, job.error);<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://verification.didit.me/v3/sessions/delete/{job_id}/",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-api-key: <api-key>"
],
]);
$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://verification.didit.me/v3/sessions/delete/{job_id}/"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-api-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://verification.didit.me/v3/sessions/delete/{job_id}/")
.header("x-api-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://verification.didit.me/v3/sessions/delete/{job_id}/")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-api-key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"job_id": "5b8f2c1e-7d3a-4f6b-9e2c-1a0d8f7e6c5b",
"status": "PROCESSING",
"total": 250,
"processed": 100,
"outcomes": {
"deleted": 82,
"none": 18,
"retained_with_user": 0,
"ineligible_no_vendor_user": 0,
"failed_retryable": 0,
"already_deleted": 0
},
"deleted_child_verifications": 0,
"error": null,
"created_at": "2026-10-09T10:15:00Z",
"completed_at": null
}Overview
Returns a bulk session deletion started by Batch Delete Sessions: its status, how many sessions it has processed, and how many ended in each outcome. When more than 20 KYC sessions match a batch delete, selected bysession_numbers or with delete_all, the request returns 202 with a PENDING job and the sessions are deleted in the background. Poll this endpoint every few seconds until status is COMPLETED or FAILED.
Each session the job deletes is deleted exactly as by Delete Session: the session, every verification attempt it holds, and all of its stored files are deleted, and its media URLs stop resolving. Deletion is permanent and irreversible.
The job reports counts only. It never lists which sessions it deleted.
Job status
status | Meaning |
|---|---|
PENDING | Accepted, not started yet. |
PROCESSING | Deleting; processed and outcomes are updating. |
COMPLETED | Every selected session is accounted for in outcomes. |
FAILED | The job stopped early and error says why. The sessions it had not reached are still in place: repeat the deletion request to delete them. |
delete_all job deletes only the sessions created before the request. Sessions started while it runs are not deleted.
Outcome counts
outcomes key | Meaning |
|---|---|
deleted | Sessions deleted together with their face embedding. |
none | Sessions deleted that had no face embedding. |
retained_with_user | Sessions deleted while one image-free biometric template was retained for their User, as the request or the application policy asked. See Delete Session. |
ineligible_no_vendor_user | Retention was requested but the session had no linked User. The session and its face embedding were deleted. |
failed_retryable | Sessions reported as not deleted. The job retries a group it could not delete by itself instead of counting it here. |
already_deleted | Selected sessions that were already deleted, for example by another request, when the job reached them. |
deleted_child_verifications counts the verifications that deleted business verifications created and that were deleted with them. It is always 0 for a job started by Batch Delete Sessions, which deletes KYC sessions only.
Permissions
Any active API key of the application can call this endpoint. A job is only visible to the application that created it; any otherjob_id returns 404.
Related
Authorizations
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 missing, wrong, revoked or expired; 403 means 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
The job_id returned with the 202 from POST /v3/sessions/delete/.
Response
The job.
A bulk session deletion running in the background: progress and counts per outcome, never which sessions it deleted.
Poll GET /v3/sessions/delete/{job_id}/ with this id.
PENDING: accepted, not started yet. PROCESSING: deleting; processed and outcomes are updating. COMPLETED: every selected session is accounted for. FAILED: the job stopped early; see error.
PENDING, PROCESSING, COMPLETED, FAILED Sessions selected when the deletion was requested.
Sessions the job has finished with so far.
How many sessions ended in each outcome. Every key is always present.
Show child attributes
Show child attributes
Verifications that the deleted business verifications created, deleted with them. Always 0 for a job started by POST /v3/sessions/delete/, which deletes KYC sessions only.
null unless status is FAILED; then why the deletion stopped. The sessions the job had not reached are still in place: repeat the request to delete them.
When the deletion was requested.
When the job finished; null while it runs.