curl --request POST \
--url https://api.interhuman.ai/v1/client_tokens \
--header 'Content-Type: application/json' \
--data '
{
"api_key": "<string>",
"scopes": [],
"expires_in": 2,
"max_duration_seconds": 2,
"max_bytes": 2,
"max_concurrent": 1,
"max_video_seconds": 2,
"allowed_origins": [
"<string>"
]
}
'import requests
url = "https://api.interhuman.ai/v1/client_tokens"
payload = {
"api_key": "<string>",
"scopes": [],
"expires_in": 2,
"max_duration_seconds": 2,
"max_bytes": 2,
"max_concurrent": 1,
"max_video_seconds": 2,
"allowed_origins": ["<string>"]
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
api_key: '<string>',
scopes: [],
expires_in: 2,
max_duration_seconds: 2,
max_bytes: 2,
max_concurrent: 1,
max_video_seconds: 2,
allowed_origins: ['<string>']
})
};
fetch('https://api.interhuman.ai/v1/client_tokens', 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/client_tokens",
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([
'api_key' => '<string>',
'scopes' => [
],
'expires_in' => 2,
'max_duration_seconds' => 2,
'max_bytes' => 2,
'max_concurrent' => 1,
'max_video_seconds' => 2,
'allowed_origins' => [
'<string>'
]
]),
CURLOPT_HTTPHEADER => [
"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.interhuman.ai/v1/client_tokens"
payload := strings.NewReader("{\n \"api_key\": \"<string>\",\n \"scopes\": [],\n \"expires_in\": 2,\n \"max_duration_seconds\": 2,\n \"max_bytes\": 2,\n \"max_concurrent\": 1,\n \"max_video_seconds\": 2,\n \"allowed_origins\": [\n \"<string>\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
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.interhuman.ai/v1/client_tokens")
.header("Content-Type", "application/json")
.body("{\n \"api_key\": \"<string>\",\n \"scopes\": [],\n \"expires_in\": 2,\n \"max_duration_seconds\": 2,\n \"max_bytes\": 2,\n \"max_concurrent\": 1,\n \"max_video_seconds\": 2,\n \"allowed_origins\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.interhuman.ai/v1/client_tokens")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"api_key\": \"<string>\",\n \"scopes\": [],\n \"expires_in\": 2,\n \"max_duration_seconds\": 2,\n \"max_bytes\": 2,\n \"max_concurrent\": 1,\n \"max_video_seconds\": 2,\n \"allowed_origins\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 300,
"scope": "interhumanai.stream",
"max_duration_seconds": 600,
"max_bytes": 52428800,
"max_concurrent": 1,
"allowed_origins": [
"https://app.example.com"
]
}{
"error_id": "<string>",
"correlation_id": "<string>",
"link": "<string>",
"message": "<string>"
}{
"error_id": "<string>",
"correlation_id": "<string>",
"link": "<string>",
"message": "<string>"
}{
"error_id": "<string>",
"correlation_id": "<string>",
"link": "<string>",
"message": "<string>"
}{
"error_id": "<string>",
"correlation_id": "<string>",
"link": "<string>",
"message": "<string>"
}{
"error_id": "<string>",
"correlation_id": "<string>",
"link": "<string>",
"message": "<string>"
}Client Tokens
curl --request POST \
--url https://api.interhuman.ai/v1/client_tokens \
--header 'Content-Type: application/json' \
--data '
{
"api_key": "<string>",
"scopes": [],
"expires_in": 2,
"max_duration_seconds": 2,
"max_bytes": 2,
"max_concurrent": 1,
"max_video_seconds": 2,
"allowed_origins": [
"<string>"
]
}
'import requests
url = "https://api.interhuman.ai/v1/client_tokens"
payload = {
"api_key": "<string>",
"scopes": [],
"expires_in": 2,
"max_duration_seconds": 2,
"max_bytes": 2,
"max_concurrent": 1,
"max_video_seconds": 2,
"allowed_origins": ["<string>"]
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
api_key: '<string>',
scopes: [],
expires_in: 2,
max_duration_seconds: 2,
max_bytes: 2,
max_concurrent: 1,
max_video_seconds: 2,
allowed_origins: ['<string>']
})
};
fetch('https://api.interhuman.ai/v1/client_tokens', 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/client_tokens",
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([
'api_key' => '<string>',
'scopes' => [
],
'expires_in' => 2,
'max_duration_seconds' => 2,
'max_bytes' => 2,
'max_concurrent' => 1,
'max_video_seconds' => 2,
'allowed_origins' => [
'<string>'
]
]),
CURLOPT_HTTPHEADER => [
"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.interhuman.ai/v1/client_tokens"
payload := strings.NewReader("{\n \"api_key\": \"<string>\",\n \"scopes\": [],\n \"expires_in\": 2,\n \"max_duration_seconds\": 2,\n \"max_bytes\": 2,\n \"max_concurrent\": 1,\n \"max_video_seconds\": 2,\n \"allowed_origins\": [\n \"<string>\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
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.interhuman.ai/v1/client_tokens")
.header("Content-Type", "application/json")
.body("{\n \"api_key\": \"<string>\",\n \"scopes\": [],\n \"expires_in\": 2,\n \"max_duration_seconds\": 2,\n \"max_bytes\": 2,\n \"max_concurrent\": 1,\n \"max_video_seconds\": 2,\n \"allowed_origins\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.interhuman.ai/v1/client_tokens")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"api_key\": \"<string>\",\n \"scopes\": [],\n \"expires_in\": 2,\n \"max_duration_seconds\": 2,\n \"max_bytes\": 2,\n \"max_concurrent\": 1,\n \"max_video_seconds\": 2,\n \"allowed_origins\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 300,
"scope": "interhumanai.stream",
"max_duration_seconds": 600,
"max_bytes": 52428800,
"max_concurrent": 1,
"allowed_origins": [
"https://app.example.com"
]
}{
"error_id": "<string>",
"correlation_id": "<string>",
"link": "<string>",
"message": "<string>"
}{
"error_id": "<string>",
"correlation_id": "<string>",
"link": "<string>",
"message": "<string>"
}{
"error_id": "<string>",
"correlation_id": "<string>",
"link": "<string>",
"message": "<string>"
}{
"error_id": "<string>",
"correlation_id": "<string>",
"link": "<string>",
"message": "<string>"
}{
"error_id": "<string>",
"correlation_id": "<string>",
"link": "<string>",
"message": "<string>"
}Response Headers
f47ac10b-58cc-4372-a567-0e02b2c3d479Headers
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
Request schema for minting an ephemeral, capped client token.
Your full API key from the Interhuman dashboard.
Scopes to grant the token. Defaults to interhumanai.stream. The key must itself hold every requested scope. A realtime session requires interhumanai.realtime. The per-token caps are enforced on streaming sessions (stream / realtime); the video budget additionally spans upload.
1Scopes define which endpoints, and which models, the API key can call.
A scope names one operation, or one (operation, model) cell of the Inter-2
routes. The bare operation scopes are the Inter-1 cells; a model scope is
the operation followed by the exact model value the route accepts.
Options:
- interhumanai.upload for /v1/upload/analyze (Inter-1)
- interhumanai.stream for /v1/stream/analyze (Inter-1)
- interhumanai.realtime for /v0/realtime/analyze
- interhumanai.upload.inter-2 for /v2/upload/analyze with
model=inter-2 - interhumanai.upload.inter-2-audio for /v2/upload/analyze with
model=inter-2-audio - interhumanai.upload.inter-2-deep for /v2/upload/analyze with
model=inter-2-deep - interhumanai.stream.inter-2 for /v2/stream/analyze with
model=inter-2 - interhumanai.stream.inter-2-audio for /v2/stream/analyze with
model=inter-2-audio
Any interhumanai.upload.<model> scope also allows reading the account's
upload jobs at /v2/upload/jobs/{job_id}. There is no stream scope for
inter-2-deep: it is an upload-only model.
interhumanai.upload, interhumanai.stream, interhumanai.realtime, interhumanai.upload.inter-2, interhumanai.upload.inter-2-audio, interhumanai.upload.inter-2-deep, interhumanai.stream.inter-2, interhumanai.stream.inter-2-audio Requested time-to-live in seconds. Clamped to the supported range (60–3600s). Omit to use the default. The response expires_in is authoritative.
x >= 1Maximum wall-clock duration of a streaming session (stream or realtime) opened with this token.
x >= 1Maximum cumulative video bytes a session opened with this token may send.
x >= 1Maximum number of concurrent streaming sessions opened with this token. Defaults to 1 (a minted token can drive only one session at a time); raise it only if a single token must power several simultaneous sessions.
x >= 1Maximum total seconds of video the token may process across upload, stream, and realtime combined. Metered server-side; when exhausted, further processing is refused and the client must mint a new token.
x >= 1Allow-list of browser Origin values permitted to use this token. When set, a connection whose Origin is absent or not listed is rejected.
Response
Successful Response
Response schema for a minted ephemeral client token.
The generated client token.
Time in seconds until the token expires.
Space-separated list of granted scopes.
Token type. Always Bearer.
Per-token max session duration that will be enforced, if any.
Per-token max cumulative session bytes that will be enforced, if any.
Per-token max concurrent sessions that will be enforced, if any.
Per-token total video-seconds budget that will be enforced, if any.
Per-token allow-list of browser origins that will be enforced, if any.