curl --request POST \
--url https://api.tuteliq.ai/api/v1/safety/tfgbv \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"text": "<string>",
"context": {
"language": "<string>",
"age_group": "<string>",
"ageGroup": "<string>",
"platform": "<string>",
"country": "<string>",
"prior_messages": [
{
"role": "<string>",
"text": "<string>",
"timestamp": "<string>"
}
],
"conversation_history": [
{
"role": "<string>",
"text": "<string>",
"timestamp": "<string>"
}
]
},
"options": {
"include_evidence": true,
"support_threshold": "high",
"verdict_only": false
},
"include_evidence": true,
"continuation_token": "<string>",
"reset_conversation": true,
"message_id": "<string>",
"bypass_cache": true,
"external_id": "<string>",
"customer_id": "<string>",
"metadata": {},
"incident_moderation_enabled": true
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
text: '<string>',
context: {
language: '<string>',
age_group: '<string>',
ageGroup: '<string>',
platform: '<string>',
country: '<string>',
prior_messages: [{role: '<string>', text: '<string>', timestamp: '<string>'}],
conversation_history: [{role: '<string>', text: '<string>', timestamp: '<string>'}]
},
options: {include_evidence: true, support_threshold: 'high', verdict_only: false},
include_evidence: true,
continuation_token: '<string>',
reset_conversation: true,
message_id: '<string>',
bypass_cache: true,
external_id: '<string>',
customer_id: '<string>',
metadata: {},
incident_moderation_enabled: true
})
};
fetch('https://api.tuteliq.ai/api/v1/safety/tfgbv', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.tuteliq.ai/api/v1/safety/tfgbv"
payload = {
"text": "<string>",
"context": {
"language": "<string>",
"age_group": "<string>",
"ageGroup": "<string>",
"platform": "<string>",
"country": "<string>",
"prior_messages": [
{
"role": "<string>",
"text": "<string>",
"timestamp": "<string>"
}
],
"conversation_history": [
{
"role": "<string>",
"text": "<string>",
"timestamp": "<string>"
}
]
},
"options": {
"include_evidence": True,
"support_threshold": "high",
"verdict_only": False
},
"include_evidence": True,
"continuation_token": "<string>",
"reset_conversation": True,
"message_id": "<string>",
"bypass_cache": True,
"external_id": "<string>",
"customer_id": "<string>",
"metadata": {},
"incident_moderation_enabled": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)val client = OkHttpClient()
val mediaType = MediaType.parse("application/json")
val body = RequestBody.create(mediaType, "{\n \"text\": \"<string>\",\n \"context\": {\n \"language\": \"<string>\",\n \"age_group\": \"<string>\",\n \"ageGroup\": \"<string>\",\n \"platform\": \"<string>\",\n \"country\": \"<string>\",\n \"prior_messages\": [\n {\n \"role\": \"<string>\",\n \"text\": \"<string>\",\n \"timestamp\": \"<string>\"\n }\n ],\n \"conversation_history\": [\n {\n \"role\": \"<string>\",\n \"text\": \"<string>\",\n \"timestamp\": \"<string>\"\n }\n ]\n },\n \"options\": {\n \"include_evidence\": true,\n \"support_threshold\": \"high\",\n \"verdict_only\": false\n },\n \"include_evidence\": true,\n \"continuation_token\": \"<string>\",\n \"reset_conversation\": true,\n \"message_id\": \"<string>\",\n \"bypass_cache\": true,\n \"external_id\": \"<string>\",\n \"customer_id\": \"<string>\",\n \"metadata\": {},\n \"incident_moderation_enabled\": true\n}")
val request = Request.Builder()
.url("https://api.tuteliq.ai/api/v1/safety/tfgbv")
.post(body)
.addHeader("Authorization", "Bearer <token>")
.addHeader("Content-Type", "application/json")
.build()
val response = client.newCall(request).execute()import Foundation
let parameters = [
"text": "<string>",
"context": [
"language": "<string>",
"age_group": "<string>",
"ageGroup": "<string>",
"platform": "<string>",
"country": "<string>",
"prior_messages": [
[
"role": "<string>",
"text": "<string>",
"timestamp": "<string>"
]
],
"conversation_history": [
[
"role": "<string>",
"text": "<string>",
"timestamp": "<string>"
]
]
],
"options": [
"include_evidence": true,
"support_threshold": "high",
"verdict_only": false
],
"include_evidence": true,
"continuation_token": "<string>",
"reset_conversation": true,
"message_id": "<string>",
"bypass_cache": true,
"external_id": "<string>",
"customer_id": "<string>",
"metadata": [],
"incident_moderation_enabled": true
] as [String : Any?]
let postData = try JSONSerialization.data(withJSONObject: parameters, options: [])
let url = URL(string: "https://api.tuteliq.ai/api/v1/safety/tfgbv")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.timeoutInterval = 10
request.allHTTPHeaderFields = [
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
]
request.httpBody = postData
let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))using RestSharp;
var options = new RestClientOptions("https://api.tuteliq.ai/api/v1/safety/tfgbv");
var client = new RestClient(options);
var request = new RestRequest("");
request.AddHeader("Authorization", "Bearer <token>");
request.AddJsonBody("{\n \"text\": \"<string>\",\n \"context\": {\n \"language\": \"<string>\",\n \"age_group\": \"<string>\",\n \"ageGroup\": \"<string>\",\n \"platform\": \"<string>\",\n \"country\": \"<string>\",\n \"prior_messages\": [\n {\n \"role\": \"<string>\",\n \"text\": \"<string>\",\n \"timestamp\": \"<string>\"\n }\n ],\n \"conversation_history\": [\n {\n \"role\": \"<string>\",\n \"text\": \"<string>\",\n \"timestamp\": \"<string>\"\n }\n ]\n },\n \"options\": {\n \"include_evidence\": true,\n \"support_threshold\": \"high\",\n \"verdict_only\": false\n },\n \"include_evidence\": true,\n \"continuation_token\": \"<string>\",\n \"reset_conversation\": true,\n \"message_id\": \"<string>\",\n \"bypass_cache\": true,\n \"external_id\": \"<string>\",\n \"customer_id\": \"<string>\",\n \"metadata\": {},\n \"incident_moderation_enabled\": true\n}", false);
var response = await client.PostAsync(request);
Console.WriteLine("{0}", response.Content);
false{
"conversation_type_applied": "<string>",
"absence_reason_cleared": true,
"endpoint": "<string>",
"detected": true,
"severity": 123,
"confidence": 123,
"risk_score": 123,
"level": "none",
"categories": [
{
"tag": "<string>",
"label": "<string>",
"confidence": 123
}
],
"evidence": [
{
"text": "<string>",
"tactic": "<string>",
"weight": 123
}
],
"age_calibration": {
"applied": true,
"age_group": "<string>",
"multiplier": 123
},
"recommended_action": "<string>",
"rationale": "<string>",
"message_analysis": [
{
"message_index": 123,
"risk_score": 123,
"flags": [
"<string>"
],
"summary": "<string>"
}
],
"language": "<string>",
"language_status": "stable",
"credits_used": 123,
"processing_time_ms": 123,
"continuation_token": "<string>",
"continuation_expires_at": "<string>",
"state_source": "token",
"external_id": "<string>",
"customer_id": "<string>",
"metadata": {},
"support": {
"country": "<string>",
"country_name": "<string>",
"emergency_number": "<string>",
"helplines": [
{
"name": "<string>",
"number": "<string>",
"description": "<string>",
"category": "<string>",
"available": "<string>"
}
],
"response_guide": {
"category": "<string>",
"immediateActions": [
"<string>"
],
"resources": [
{
"name": "<string>",
"description": "<string>",
"url": "<string>"
}
]
}
}
}Detect tech-facilitated gender-based violence
Analyzes text for tech-facilitated gender-based violence (TFGBV) patterns including image-based abuse, cyber stalking, online harassment, doxing, impersonation, outing, post-separation abuse, sextortion, digital coercion, sexualised deepfakes, and gendered hate speech. Returns TFGBV amplifier assessment and intersectionality flags.
curl --request POST \
--url https://api.tuteliq.ai/api/v1/safety/tfgbv \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"text": "<string>",
"context": {
"language": "<string>",
"age_group": "<string>",
"ageGroup": "<string>",
"platform": "<string>",
"country": "<string>",
"prior_messages": [
{
"role": "<string>",
"text": "<string>",
"timestamp": "<string>"
}
],
"conversation_history": [
{
"role": "<string>",
"text": "<string>",
"timestamp": "<string>"
}
]
},
"options": {
"include_evidence": true,
"support_threshold": "high",
"verdict_only": false
},
"include_evidence": true,
"continuation_token": "<string>",
"reset_conversation": true,
"message_id": "<string>",
"bypass_cache": true,
"external_id": "<string>",
"customer_id": "<string>",
"metadata": {},
"incident_moderation_enabled": true
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
text: '<string>',
context: {
language: '<string>',
age_group: '<string>',
ageGroup: '<string>',
platform: '<string>',
country: '<string>',
prior_messages: [{role: '<string>', text: '<string>', timestamp: '<string>'}],
conversation_history: [{role: '<string>', text: '<string>', timestamp: '<string>'}]
},
options: {include_evidence: true, support_threshold: 'high', verdict_only: false},
include_evidence: true,
continuation_token: '<string>',
reset_conversation: true,
message_id: '<string>',
bypass_cache: true,
external_id: '<string>',
customer_id: '<string>',
metadata: {},
incident_moderation_enabled: true
})
};
fetch('https://api.tuteliq.ai/api/v1/safety/tfgbv', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.tuteliq.ai/api/v1/safety/tfgbv"
payload = {
"text": "<string>",
"context": {
"language": "<string>",
"age_group": "<string>",
"ageGroup": "<string>",
"platform": "<string>",
"country": "<string>",
"prior_messages": [
{
"role": "<string>",
"text": "<string>",
"timestamp": "<string>"
}
],
"conversation_history": [
{
"role": "<string>",
"text": "<string>",
"timestamp": "<string>"
}
]
},
"options": {
"include_evidence": True,
"support_threshold": "high",
"verdict_only": False
},
"include_evidence": True,
"continuation_token": "<string>",
"reset_conversation": True,
"message_id": "<string>",
"bypass_cache": True,
"external_id": "<string>",
"customer_id": "<string>",
"metadata": {},
"incident_moderation_enabled": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)val client = OkHttpClient()
val mediaType = MediaType.parse("application/json")
val body = RequestBody.create(mediaType, "{\n \"text\": \"<string>\",\n \"context\": {\n \"language\": \"<string>\",\n \"age_group\": \"<string>\",\n \"ageGroup\": \"<string>\",\n \"platform\": \"<string>\",\n \"country\": \"<string>\",\n \"prior_messages\": [\n {\n \"role\": \"<string>\",\n \"text\": \"<string>\",\n \"timestamp\": \"<string>\"\n }\n ],\n \"conversation_history\": [\n {\n \"role\": \"<string>\",\n \"text\": \"<string>\",\n \"timestamp\": \"<string>\"\n }\n ]\n },\n \"options\": {\n \"include_evidence\": true,\n \"support_threshold\": \"high\",\n \"verdict_only\": false\n },\n \"include_evidence\": true,\n \"continuation_token\": \"<string>\",\n \"reset_conversation\": true,\n \"message_id\": \"<string>\",\n \"bypass_cache\": true,\n \"external_id\": \"<string>\",\n \"customer_id\": \"<string>\",\n \"metadata\": {},\n \"incident_moderation_enabled\": true\n}")
val request = Request.Builder()
.url("https://api.tuteliq.ai/api/v1/safety/tfgbv")
.post(body)
.addHeader("Authorization", "Bearer <token>")
.addHeader("Content-Type", "application/json")
.build()
val response = client.newCall(request).execute()import Foundation
let parameters = [
"text": "<string>",
"context": [
"language": "<string>",
"age_group": "<string>",
"ageGroup": "<string>",
"platform": "<string>",
"country": "<string>",
"prior_messages": [
[
"role": "<string>",
"text": "<string>",
"timestamp": "<string>"
]
],
"conversation_history": [
[
"role": "<string>",
"text": "<string>",
"timestamp": "<string>"
]
]
],
"options": [
"include_evidence": true,
"support_threshold": "high",
"verdict_only": false
],
"include_evidence": true,
"continuation_token": "<string>",
"reset_conversation": true,
"message_id": "<string>",
"bypass_cache": true,
"external_id": "<string>",
"customer_id": "<string>",
"metadata": [],
"incident_moderation_enabled": true
] as [String : Any?]
let postData = try JSONSerialization.data(withJSONObject: parameters, options: [])
let url = URL(string: "https://api.tuteliq.ai/api/v1/safety/tfgbv")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.timeoutInterval = 10
request.allHTTPHeaderFields = [
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
]
request.httpBody = postData
let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))using RestSharp;
var options = new RestClientOptions("https://api.tuteliq.ai/api/v1/safety/tfgbv");
var client = new RestClient(options);
var request = new RestRequest("");
request.AddHeader("Authorization", "Bearer <token>");
request.AddJsonBody("{\n \"text\": \"<string>\",\n \"context\": {\n \"language\": \"<string>\",\n \"age_group\": \"<string>\",\n \"ageGroup\": \"<string>\",\n \"platform\": \"<string>\",\n \"country\": \"<string>\",\n \"prior_messages\": [\n {\n \"role\": \"<string>\",\n \"text\": \"<string>\",\n \"timestamp\": \"<string>\"\n }\n ],\n \"conversation_history\": [\n {\n \"role\": \"<string>\",\n \"text\": \"<string>\",\n \"timestamp\": \"<string>\"\n }\n ]\n },\n \"options\": {\n \"include_evidence\": true,\n \"support_threshold\": \"high\",\n \"verdict_only\": false\n },\n \"include_evidence\": true,\n \"continuation_token\": \"<string>\",\n \"reset_conversation\": true,\n \"message_id\": \"<string>\",\n \"bypass_cache\": true,\n \"external_id\": \"<string>\",\n \"customer_id\": \"<string>\",\n \"metadata\": {},\n \"incident_moderation_enabled\": true\n}", false);
var response = await client.PostAsync(request);
Console.WriteLine("{0}", response.Content);
false{
"conversation_type_applied": "<string>",
"absence_reason_cleared": true,
"endpoint": "<string>",
"detected": true,
"severity": 123,
"confidence": 123,
"risk_score": 123,
"level": "none",
"categories": [
{
"tag": "<string>",
"label": "<string>",
"confidence": 123
}
],
"evidence": [
{
"text": "<string>",
"tactic": "<string>",
"weight": 123
}
],
"age_calibration": {
"applied": true,
"age_group": "<string>",
"multiplier": 123
},
"recommended_action": "<string>",
"rationale": "<string>",
"message_analysis": [
{
"message_index": 123,
"risk_score": 123,
"flags": [
"<string>"
],
"summary": "<string>"
}
],
"language": "<string>",
"language_status": "stable",
"credits_used": 123,
"processing_time_ms": 123,
"continuation_token": "<string>",
"continuation_expires_at": "<string>",
"state_source": "token",
"external_id": "<string>",
"customer_id": "<string>",
"metadata": {},
"support": {
"country": "<string>",
"country_name": "<string>",
"emergency_number": "<string>",
"helplines": [
{
"name": "<string>",
"number": "<string>",
"description": "<string>",
"category": "<string>",
"available": "<string>"
}
],
"response_guide": {
"category": "<string>",
"immediateActions": [
"<string>"
],
"resources": [
{
"name": "<string>",
"description": "<string>",
"url": "<string>"
}
]
}
}
}Authorizations
API key as Bearer token
Body
The text content to analyze
10000Show child attributes
Show child attributes
Show child attributes
Show child attributes
Top-level alias for options.support_threshold. Minimum severity to show crisis support resources (default: high). Critical always shows.
low, medium, high, critical Top-level alias for options.include_evidence. When false, the evidence array is omitted from the response. Default: true.
Opaque, signed token returned by a previous call to this endpoint. Pass it back here to continue the analysis with prior context — no need to re-send prior_messages. The token IS the state; we store nothing.
When true, discard any continuation_token and treat this call as the first turn of a new conversation.
Optional customer-side identifier for this turn. If provided, evidence pointers in the continuation_token will reference this id so you can map detections back to your own messages. If omitted we use a deterministic short hash of the text.
128Deprecated, no effect: results are never cached — every request runs a fresh evaluation and nothing derived from the input is stored. The field is still accepted so existing integrations do not break.
Your unique identifier (e.g. message ID, content ID) for correlating Tuteliq results with your own system. Echoed back in the response and included in webhook payloads so you can match alerts to the original content.
255Your end-customer identifier for multi-tenant / B2B2C scenarios. If you serve multiple customers (schools, apps, brands) from a single API key, set this to route webhook alerts to the correct customer. Echoed back in the response and included in webhook payloads as "customerId".
255Arbitrary key-value pairs for additional context (e.g. { "channel": "discord", "region": "eu" }). Stored with the detection result, echoed in the response, and included in webhook payloads. Maximum 20 properties.
Per-call override of your account incident logging setting. When set, it takes precedence for THIS request: true forces the incident to be persisted, false suppresses persistence. Omit to use your account default (which itself defaults to enabled). Useful to suppress logging for test traffic or to opt specific calls in or out.
Response
Default Response
Present only when a caller-declared context.conversation_type actually changed routing. Confirms the setting was taken into account, rather than leaving the platform to assume it was.
romance-scam only. Present when a detection was cleared because the reason given for not appearing on video or in person was a passing obstacle (a router down, out of data, an early start) rather than a standing property of the claimed persona (a deployment, a rig, a clearance), and the only tactics were IDENTITY_FABRICATION / SECRECY_REQUEST / URGENCY_PRESSURE. Before this, an ordinary "no wifi until Thursday" message was told its sender was fabricating an identity (#224). Absent when the gate did not fire.
The detection endpoint that produced this result
A signal was observed at ANY severity (including low / monitor cases). For production branching prefer recommended_action (flag_for_moderator / immediate_intervention indicate action required).
Severity score (0.0-1.0)
Model confidence in the classification (0.0-1.0)
Age-adjusted risk score (0.0-1.0)
Human-readable severity level
none, low, medium, high, critical Detected categories with confidence scores
Show child attributes
Show child attributes
Evidence excerpts supporting the detection
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Recommended action to take
Explanation of the detection result
Per-message risk breakdown (only present when prior_messages is provided)
Show child attributes
Show child attributes
Language code used for analysis
Language support maturity
stable, beta Credits consumed by this request
Processing time in milliseconds
Opaque, signed token carrying derived analysis state. Pass it back on the next call to continue the conversation without re-sending history. Server stores nothing — the token IS the state.
ISO 8601 timestamp at which the continuation_token expires (24h default).
How the prior analysis state was sourced for this call: "token" (decoded from continuation_token), "fresh" (no prior state), "reset" (reset_conversation forced a fresh start).
token, fresh, reset Echo of the external_id you provided in the request
Echo of the customer_id you provided in the request
Echo of the metadata you provided in the request
Country-specific crisis helplines and response guidance (only for high/critical severity)
Show child attributes
Show child attributes