curl --request POST \
--url https://api.interhuman.ai/v1/upload/analyze \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form file='@example-file' \
--form conversation_context=import requests
url = "https://api.interhuman.ai/v1/upload/analyze"
files = { "file": ("example-file", open("example-file", "rb")) }
payload = { "conversation_context": "" }
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('file', '<string>');
form.append('conversation_context', '');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://api.interhuman.ai/v1/upload/analyze', 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.interhuman.ai/v1/upload/analyze",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"conversation_context\"\r\n\r\n\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: multipart/form-data"
],
]);
$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.interhuman.ai/v1/upload/analyze"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"conversation_context\"\r\n\r\n\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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.interhuman.ai/v1/upload/analyze")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"conversation_context\"\r\n\r\n\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.interhuman.ai/v1/upload/analyze")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"conversation_context\"\r\n\r\n\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"signals": [
{
"type": "agreement",
"start": 0,
"end": 10,
"probability": "high",
"rationale": "Subject nodded repeatedly while maintaining eye contact."
},
{
"type": "confidence",
"start": 5,
"end": 15,
"probability": "medium",
"rationale": "Steady voice with minimal hesitation."
}
],
"engagement_state": [
{
"start": 0,
"end": 5,
"state": "engaged"
},
{
"start": 5,
"end": 15,
"state": "neutral"
}
],
"conversation_quality": {
"overall": {
"quality_index": 72,
"clarity": 67,
"authority": 68,
"energy": 80,
"rapport": 75,
"learning": 70
},
"timeline": [
{
"start": 0,
"end": 10,
"values": {
"quality_index": 70,
"clarity": 69,
"authority": 70,
"energy": 78,
"rapport": 77,
"learning": 68
}
},
{
"start": 10,
"end": 20,
"values": {
"quality_index": 74,
"clarity": 65,
"authority": 65,
"energy": 82,
"rapport": 73,
"learning": 72
}
}
]
}
}Inter-1 Upload Analyze
Analyze a video file in upload mode.
curl --request POST \
--url https://api.interhuman.ai/v1/upload/analyze \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form file='@example-file' \
--form conversation_context=import requests
url = "https://api.interhuman.ai/v1/upload/analyze"
files = { "file": ("example-file", open("example-file", "rb")) }
payload = { "conversation_context": "" }
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('file', '<string>');
form.append('conversation_context', '');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://api.interhuman.ai/v1/upload/analyze', 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.interhuman.ai/v1/upload/analyze",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"conversation_context\"\r\n\r\n\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: multipart/form-data"
],
]);
$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.interhuman.ai/v1/upload/analyze"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"conversation_context\"\r\n\r\n\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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.interhuman.ai/v1/upload/analyze")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"conversation_context\"\r\n\r\n\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.interhuman.ai/v1/upload/analyze")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"conversation_context\"\r\n\r\n\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"signals": [
{
"type": "agreement",
"start": 0,
"end": 10,
"probability": "high",
"rationale": "Subject nodded repeatedly while maintaining eye contact."
},
{
"type": "confidence",
"start": 5,
"end": 15,
"probability": "medium",
"rationale": "Steady voice with minimal hesitation."
}
],
"engagement_state": [
{
"start": 0,
"end": 5,
"state": "engaged"
},
{
"start": 5,
"end": 15,
"state": "neutral"
}
],
"conversation_quality": {
"overall": {
"quality_index": 72,
"clarity": 67,
"authority": 68,
"energy": 80,
"rapport": 75,
"learning": 70
},
"timeline": [
{
"start": 0,
"end": 10,
"values": {
"quality_index": 70,
"clarity": 69,
"authority": 70,
"energy": 78,
"rapport": 77,
"learning": 68
}
},
{
"start": 10,
"end": 20,
"values": {
"quality_index": 74,
"clarity": 65,
"authority": 65,
"energy": 82,
"rapport": 73,
"learning": 72
}
}
]
}
}Response Headers
f47ac10b-58cc-4372-a567-0e02b2c3d479Authorizations
API key authentication. Include your API key in the Authorization header as 'Bearer <api_key>'.
Headers
Optional identifier supplied by the client to correlate this request with their own logs. When provided, the value is recorded alongside the server-assigned correlation ID in Interhuman logs to aid lookup and support investigations. This header is not echoed back in the response; the server returns its own correlation ID in the X-Correlation-ID HTTP response header.
Optional client SDK identity as <sdk-name>/<semver> (e.g. typescript/0.13.0), sent automatically by the first-party Interhuman SDKs. It is recorded in Interhuman telemetry so SDK adoption and version distribution are visible. The value is self-declared and not authenticated: it never affects authentication, authorization, scopes, quotas, or billing, and a missing, malformed, or unrecognized value is ignored rather than rejected.
Body
Video file to analyze. The video must be at least 3 seconds long and the upload must not exceed 32MB. Accepts the following formats: mp4, avi, mov, mkv, mpeg-ts, webm.
Optional flags indicating which sections should be included in the response. When omitted, no optional sections are included.
Use these flags to control which conversation quality sections are included in the response.
conversation_quality_overall: Include overall conversation quality index.
conversation_quality_timeline: Include conversation quality timeline.
conversation_quality_overall, conversation_quality_timeline Optional conversation-quality goal dimensions for this interaction. Supplying at least one goal dimension triggers feedback generation. Ignored when conversation_context is supplied — that field then drives feedback generation on its own.
Conversation quality dimensions a caller can flag as a session goal.
The values map one-to-one onto the five CQI quality dimensions defined in
services.cqi.DIMENSION_KEYS:
clarity— Clarity / Structureauthority— Authority / Credibilityenergy— Energy / Presencerapport— Rapport / Relational Safetylearning— Learning / Exploration
clarity, authority, energy, rapport, learning Optional free-text description of the interaction scenario, role, or communication goal. Used as the sole source of context for feedback generation; goal dimensions are ignored when this context is supplied.
Response
Successful Response
Contains the result of the video analysis.
List of all social signals detected in the analyzed video.
Show child attributes
Show child attributes
[
{
"end": 10,
"probability": "high",
"rationale": "Subject nodded repeatedly while maintaining eye contact.",
"start": 0,
"type": "agreement"
},
{
"end": 15,
"probability": "medium",
"rationale": "Steady voice with minimal hesitation.",
"start": 5,
"type": "confidence"
}
]
Time-varying engagement state derived from detected engagement signals. Each entry covers a contiguous time window with a single state: 'engaged' when engagement is detected, 'disengaged' when disengagement is detected, 'neutral' otherwise.
Show child attributes
Show child attributes
[
{ "end": 5, "start": 0, "state": "engaged" },
{ "end": 15, "start": 5, "state": "neutral" }
]
Structured interaction feedback returned by the coach model.
Discriminated on type: a feedback result populates message,
active_dimensions, and primary_signal; a no_feedback result
populates reason instead.
Show child attributes
Show child attributes
{
"active_dimensions": ["clarity", "energy"],
"message": "You restarted several phrases and looked away near the end, while clarity and energy dropped. Pause, choose one direct sentence, and lead with the main point before adding nuance.",
"primary_signal": "hesitation",
"type": "feedback"
}
Conversation quality Index with optional overall and time-varying scores.
Use the Include flags in the request to control which conversation quality sections are included in the response.
Show child attributes
Show child attributes
{
"overall": {
"authority": 68,
"clarity": 67,
"energy": 80,
"learning": 70,
"quality_index": 72,
"rapport": 75
},
"timeline": [
{
"end": 10,
"start": 0,
"values": {
"authority": 70,
"clarity": 69,
"energy": 78,
"learning": 68,
"quality_index": 70,
"rapport": 77
}
},
{
"end": 20,
"start": 10,
"values": {
"authority": 65,
"clarity": 65,
"energy": 82,
"learning": 72,
"quality_index": 74,
"rapport": 73
}
}
]
}