curl --request POST \
--url https://api.spoofsense.ai/v1/verification_sessions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"products": [
"face_liveness",
"deepfake"
],
"reference_id": "user_123"
}
'import requests
url = "https://api.spoofsense.ai/v1/verification_sessions"
payload = {
"products": ["face_liveness", "deepfake"],
"reference_id": "user_123"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({products: ['face_liveness', 'deepfake'], reference_id: 'user_123'})
};
fetch('https://api.spoofsense.ai/v1/verification_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.spoofsense.ai/v1/verification_sessions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'products' => [
'face_liveness',
'deepfake'
],
'reference_id' => 'user_123'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.spoofsense.ai/v1/verification_sessions"
payload := strings.NewReader("{\n \"products\": [\n \"face_liveness\",\n \"deepfake\"\n ],\n \"reference_id\": \"user_123\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
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.spoofsense.ai/v1/verification_sessions")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"products\": [\n \"face_liveness\",\n \"deepfake\"\n ],\n \"reference_id\": \"user_123\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.spoofsense.ai/v1/verification_sessions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"products\": [\n \"face_liveness\",\n \"deepfake\"\n ],\n \"reference_id\": \"user_123\"\n}"
response = http.request(request)
puts response.read_body{
"object": "verification_session",
"id": "vs_1f2e3d4c5b6a79880917263544332211",
"status": "created",
"client_token": "sst_Zk9qX1J2c3Q0dTV2Nnc3eDh5OXow",
"nonce": "8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f",
"products": [
"face_liveness",
"deepfake"
],
"reference_id": "user_123",
"expires_at": "2026-01-01T12:15:00+00:00",
"created_at": "2026-01-01T12:00:00+00:00"
}{
"error": {
"code": "BAD_REQUEST",
"message": "Provide 'data' (base64) or 'image_url'"
}
}{
"error": {
"code": "UNAUTHORIZED",
"message": "Missing, invalid, or revoked API key"
}
}{
"error": {
"code": "INSUFFICIENT_CREDITS",
"message": "Insufficient credits"
}
}Create a verification session
Called from your backend with the secret key. Mints a single-use sst_ client token — returned exactly once, only its hash is stored. Products and thresholds are fixed here, server-side; the client can never change them. Fails fast with 402 if your balance is empty, so you never hand out a doomed token.
curl --request POST \
--url https://api.spoofsense.ai/v1/verification_sessions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"products": [
"face_liveness",
"deepfake"
],
"reference_id": "user_123"
}
'import requests
url = "https://api.spoofsense.ai/v1/verification_sessions"
payload = {
"products": ["face_liveness", "deepfake"],
"reference_id": "user_123"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({products: ['face_liveness', 'deepfake'], reference_id: 'user_123'})
};
fetch('https://api.spoofsense.ai/v1/verification_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.spoofsense.ai/v1/verification_sessions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'products' => [
'face_liveness',
'deepfake'
],
'reference_id' => 'user_123'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.spoofsense.ai/v1/verification_sessions"
payload := strings.NewReader("{\n \"products\": [\n \"face_liveness\",\n \"deepfake\"\n ],\n \"reference_id\": \"user_123\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
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.spoofsense.ai/v1/verification_sessions")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"products\": [\n \"face_liveness\",\n \"deepfake\"\n ],\n \"reference_id\": \"user_123\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.spoofsense.ai/v1/verification_sessions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"products\": [\n \"face_liveness\",\n \"deepfake\"\n ],\n \"reference_id\": \"user_123\"\n}"
response = http.request(request)
puts response.read_body{
"object": "verification_session",
"id": "vs_1f2e3d4c5b6a79880917263544332211",
"status": "created",
"client_token": "sst_Zk9qX1J2c3Q0dTV2Nnc3eDh5OXow",
"nonce": "8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f",
"products": [
"face_liveness",
"deepfake"
],
"reference_id": "user_123",
"expires_at": "2026-01-01T12:15:00+00:00",
"created_at": "2026-01-01T12:00:00+00:00"
}{
"error": {
"code": "BAD_REQUEST",
"message": "Provide 'data' (base64) or 'image_url'"
}
}{
"error": {
"code": "UNAUTHORIZED",
"message": "Missing, invalid, or revoked API key"
}
}{
"error": {
"code": "INSUFFICIENT_CREDITS",
"message": "Insufficient credits"
}
}Authorizations
Your secret key (sk_live_…), server-side only. Also accepted as an x-api-key header.
Body
Which checks to run on the capture. Defaults to both. Liveness only = 1 credit, deepfake only = 2, both = 3.
face_liveness, deepfake Per-product threshold override, e.g. {"face_liveness": 0.6}. Values in [0,1]. Defaults to your org settings.
Show child attributes
Show child attributes
How long the session stays usable. Clamped to 60–3600.
60 <= x <= 3600Your own user/transaction id, echoed back on reads.
256Arbitrary JSON, at most 4096 bytes, echoed back on reads.
Response
Session created
verification_session vs_… id. Keep server-side to fetch the result later.
created sst_… token for the SDK. Returned exactly once — only its hash is stored.
Bound into the submit payload; also available to the SDK via session_info.