Clients & helpers
AuthClient
Client for the token endpoints (/v1/auth and /v1/client_tokens).
Args:
environment: Named environment to call. Defaults to production.
base_url: Explicit base URL override (e.g. http://localhost:8080).
http_client: Optional shared httpx.AsyncClient. When omitted,
a client is created per request.
Constructor
AuthClient.base_url
AuthClient.create_client_token()
interhumanai.stream, 300 second lifetime clamped to 60-3600).
Args:
api_key: The full API key (ih_...) minting the token.
scopes: Scopes the client token should carry.
expires_in: Requested lifetime in seconds (server clamps to 60-3600).
max_duration_seconds: Cap on a single live session’s duration.
max_bytes: Cap on bytes accepted across the token’s sessions.
max_concurrent: Cap on concurrent sessions (server default 1).
max_video_seconds: Video-seconds budget across all surfaces.
allowed_origins: Browser origins allowed to use the token.
Returns:
The minted client token and its effective caps.
AuthClient.create_token()
AuthClient.revoke_client_token()
InterhumanClient
High-level client for the Interhuman API. Authenticate either with API key credentials (key_id + key_secret,
exchanged for short-lived bearer tokens that are refreshed automatically)
or with a pre-issued access_token used as-is. Exactly one of the two
must be provided.
The client exposes every public surface: auth for token endpoints,
upload for complete files, and stream / realtime
for live WebSocket sessions.
Args:
key_id: API key id (paired with key_secret).
key_secret: API key secret.
access_token: Pre-issued bearer token (JWT or client token).
scopes: Scopes requested when exchanging credentials. Defaults to
upload + stream. Ignored when access_token is used.
environment: Named environment to call. Defaults to production.
base_url: Explicit base URL override (e.g. http://localhost:8080).
http_client: Optional shared httpx.AsyncClient for the HTTP
surfaces. The caller owns its lifecycle.
refresh_skew_seconds: How long before expiry managed tokens refresh.
Constructor
InterhumanClient.get_token()
access_token it returns that token unchanged.
InterhumanClient.realtime()
WS /v0/realtime/analyze session.
Each call returns a fresh, unconnected client; a client handles a
single session.
InterhumanClient.stream()
WS /v1/stream/analyze session.
Each call returns a fresh, unconnected client; a client handles a
single session.
RealtimeClient
One live session againstWS /v0/realtime/analyze.
The real-time endpoint is a temporary v0 public release; it accepts
either the interhumanai.stream or the interhumanai.realtime scope.
It never emits engagement.updated or conversation_quality.updated
events, and adds transcript and feedback output on top of the stream
protocol. The previous hyphenated spelling (/v0/real-time/analyze) still
works as a temporary compatibility alias, but new integrations should use
/v0/realtime/analyze.
RealtimeClient.send_transcript()
RealtimeClient.update_config()
session.updated event.
Args:
analysis_groups: Analysis tracks to run (must be non-empty when
provided). Server default when omitted: audio and visual.
realtime_feedback_frequency: How often feedback output is generated.
realtime_feedback_instructions: Non-empty instructions that enable feedback;
when omitted or empty, feedback is disabled.
goal_dimensions: Goal dimensions that enable feedback generation.
SessionSocketClient
One live analysis session over a WebSocket. Connect withconnect (or async with), send binary video chunks
with send_video, and consume typed server events by iterating the
client with async for. Iteration ends when the connection closes;
close_info then holds the close code and reason.
Args:
token_provider: Source of bearer tokens for authentication.
environment: Named environment to connect to. Defaults to
production.
base_url: Explicit HTTP base URL override; converted to ws(s)://.
Constructor
SessionSocketClient.close()
SessionSocketClient.close_info
None.
SessionSocketClient.connect()
SessionSocketClient.is_open
SessionSocketClient.request_close()
session.closing, emits any final
events, sends session.ended, and closes the socket normally. Keep
iterating to observe the drain; for an immediate teardown use
close instead.
SessionSocketClient.send_video()
session.ready as
max_segment_size_bytes) with an ih6002 error.
Args:
chunk: The raw video bytes to send.
SessionSocketClient.url
SessionSocketClient.wait_closed()
SessionSocketClient.wait_for_session_ready()
session.ready event.
The event is also delivered through iteration; this helper simply
awaits it (or returns it if it already arrived).
Returns:
The session.ready event.
Raises:
InterhumanError: If the connection closes before the session
becomes ready (typically an auth or scope failure).
StaticTokenProvider
Token provider that always returns the same pre-issued token. ConstructorStaticTokenProvider.get_token()
StreamClient
One live session againstWS /v1/stream/analyze.
Requires the interhumanai.stream scope. Send WebM or fragmented-MP4
chunks with send_video; consume typed events with async for.
StreamClient.update_config()
session.updated event.
Args:
include: Optional sections to include in quality updates.
goal_dimensions: Goal dimensions that enable feedback generation.
TokenManager
Mints bearer tokens from API key credentials and refreshes them early. Tokens are cached untilexpires_in - refresh_skew_seconds elapses;
concurrent callers share a single in-flight mint.
Args:
auth_client: The AuthClient used to mint tokens.
key_id: The API key id.
key_secret: The API key secret.
scopes: Scopes to request on every mint.
refresh_skew_seconds: Seconds before expiry at which the cached token
is considered stale.
clock: Monotonic clock returning seconds; injectable for tests.
Constructor
TokenManager.get_token()
TokenManager.invalidate()
TokenProvider
Anything that can produce a bearer access token on demand. ConstructorTokenProvider.get_token()
UploadClient
Client for analyzing complete video files. Args: token_provider: Source of bearer tokens for authentication. environment: Named environment to call. Defaults toproduction.
base_url: Explicit base URL override.
http_client: Optional shared httpx.AsyncClient. When omitted,
a client is created per request.
Constructor
UploadClient.analyze()
video.
content_type: MIME type of the file (e.g. video/mp4).
include: Optional response sections to include (conversation
quality overall and/or timeline).
goal_dimensions: Goal dimensions that trigger interaction
feedback. Ignored when conversation_context is set.
conversation_context: Free-text description of the interaction;
when set, it drives feedback generation.
Returns:
The analysis result. Optional sections are only present when
requested.
Data models
AnalysisResult
Response ofPOST /v1/upload/analyze.
Optional sections are only present when requested: feedback when goal
dimensions or a conversation context were supplied, conversation_quality
when requested via include flags.
| Field | Type | Required |
|---|---|---|
signals | list[Signal] | No |
engagement_state | list[EngagementStateEntry] | No |
feedback | Optional[Feedback | NoFeedback] | No |
conversation_quality | ConversationQuality | None | No |
ClientTokenResponse
Response ofPOST /v1/client_tokens.
| Field | Type | Required |
|---|---|---|
access_token | str | Yes |
token_type | str | Yes |
expires_in | int | Yes |
scope | str | Yes |
max_duration_seconds | int | None | No |
max_bytes | int | None | No |
max_concurrent | int | None | No |
max_video_seconds | int | None | No |
allowed_origins | list[str] | None | No |
CloseInfo
Close code and reason of a finished WebSocket session.| Field | Type | Required |
|---|---|---|
code | int | Yes |
reason | str | Yes |
ConversationQuality
Conversation-quality section of an analysis result.| Field | Type | Required |
|---|---|---|
overall | ConversationQualityValues | Yes |
timeline | list[ConversationQualityTimelineEntry] | No |
ConversationQualityTimelineEntry
Conversation-quality scores for one slice of the video.| Field | Type | Required |
|---|---|---|
start | float | Yes |
end | float | Yes |
values | ConversationQualityValues | Yes |
ConversationQualityUpdatedData
Latest conversation-quality scores (sections follow the include flags).| Field | Type | Required |
|---|---|---|
overall | ConversationQualityValues | None | No |
timeline | list[ConversationQualityTimelineEntry] | None | No |
ConversationQualityUpdatedEvent
New conversation-quality scores are available.| Field | Type | Required |
|---|---|---|
timestamp | datetime | Yes |
correlation_id | str | Yes |
type | Literal['conversation_quality.updated'] | Yes |
data | ConversationQualityUpdatedData | Yes |
ConversationQualityValues
Conversation-quality scores (0-100; 50 means no evidence either way).| Field | Type | Required |
|---|---|---|
quality_index | float | Yes |
clarity | float | Yes |
authority | float | Yes |
energy | float | Yes |
rapport | float | Yes |
learning | float | Yes |
CoverageDroppedData
Video ranges dropped under backpressure (not billed).| Field | Type | Required |
|---|---|---|
ranges | list[CoverageRange] | No |
CoverageDroppedEvent
Some video was dropped without being analyzed.| Field | Type | Required |
|---|---|---|
timestamp | datetime | Yes |
correlation_id | str | Yes |
type | Literal['coverage.dropped'] | Yes |
data | CoverageDroppedData | Yes |
CoverageRange
A time range of video that was not analyzed.| Field | Type | Required |
|---|---|---|
start | float | Yes |
end | float | Yes |
EngagementStateEntry
An engagement state over a time range.| Field | Type | Required |
|---|---|---|
state | EngagementLevel | Yes |
start | float | Yes |
end | float | Yes |
EngagementUpdatedData
The engagement state entered atstart.
| Field | Type | Required |
|---|---|---|
state | EngagementLevel | Yes |
start | float | Yes |
EngagementUpdatedEvent
The subject’s engagement state changed.| Field | Type | Required |
|---|---|---|
timestamp | datetime | Yes |
correlation_id | str | Yes |
type | Literal['engagement.updated'] | Yes |
data | EngagementUpdatedData | Yes |
ErrorData
A session error notice (fatal errors also close the socket).| Field | Type | Required |
|---|---|---|
code | str | Yes |
message | str | Yes |
link | str | None | No |
segment | int | None | No |
ErrorEvent
The server reported an error for this session.| Field | Type | Required |
|---|---|---|
timestamp | datetime | Yes |
correlation_id | str | Yes |
type | Literal['error'] | Yes |
data | ErrorData | Yes |
Feedback
Actionable interaction feedback generated from the analysis.| Field | Type | Required |
|---|---|---|
type | Literal['feedback'] | No (default 'feedback') |
message | str | Yes |
active_dimensions | list[GoalDimension] | No |
primary_signal | SignalType | None | No |
FeedbackGeneratedData
Feedback text generated from the active goal dimensions.| Field | Type | Required |
|---|---|---|
feedback | str | Yes |
FeedbackGeneratedEvent
Interaction feedback was generated.| Field | Type | Required |
|---|---|---|
timestamp | datetime | Yes |
correlation_id | str | Yes |
type | Literal['feedback.generated'] | Yes |
data | FeedbackGeneratedData | Yes |
NoFeedback
Explicit indication that no feedback was warranted, with the reason.| Field | Type | Required |
|---|---|---|
type | Literal['no_feedback'] | No (default 'no_feedback') |
reason | str | Yes |
RealtimeFeedbackGeneratedData
Generated guidance for the analyzed window.text is the literal NO_GUIDANCE when the model had nothing to
suggest for this window.
| Field | Type | Required |
|---|---|---|
text | str | Yes |
start | float | Yes |
end | float | Yes |
RealtimeFeedbackGeneratedEvent
New feedback output is available.| Field | Type | Required |
|---|---|---|
timestamp | datetime | Yes |
correlation_id | str | Yes |
type | Literal['realtime_feedback.generated'] | Yes |
data | RealtimeFeedbackGeneratedData | Yes |
RealtimeSessionConfigOptions
Session-config options the real-time endpoint supports.| Field | Type | Required |
|---|---|---|
realtime_feedback_instructions | str | Yes |
realtime_feedback_frequency | list[RealtimeFeedbackFrequency] | Yes |
analysis_groups | list[AnalysisGroup] | Yes |
RealtimeSessionReadyData
Limits and supported options of a newly opened real-time session.| Field | Type | Required |
|---|---|---|
session_idle_timeout_seconds | int | Yes |
session_max_duration_seconds | int | Yes |
max_segment_duration_seconds | float | None | No |
min_segment_size_bytes | int | Yes |
max_segment_size_bytes | int | Yes |
supported_session_config_options | RealtimeSessionConfigOptions | Yes |
RealtimeSessionReadyEvent
The session is accepted and ready to receive video.| Field | Type | Required |
|---|---|---|
timestamp | datetime | Yes |
correlation_id | str | Yes |
type | Literal['session.ready'] | Yes |
data | RealtimeSessionReadyData | Yes |
RealtimeSessionUpdatedData
The real-time session configuration now in effect.| Field | Type | Required |
|---|---|---|
realtime_feedback_instructions | str | None | No |
realtime_feedback_frequency | RealtimeFeedbackFrequency | None | No |
analysis_groups | list[AnalysisGroup] | Yes |
RealtimeSessionUpdatedEvent
Acknowledgment of a session-config update.| Field | Type | Required |
|---|---|---|
timestamp | datetime | Yes |
correlation_id | str | Yes |
type | Literal['session.updated'] | Yes |
data | RealtimeSessionUpdatedData | Yes |
SessionClosingData
Drain window granted after a graceful close request.| Field | Type | Required |
|---|---|---|
max_drain_seconds | int | Yes |
SessionClosingEvent
The server accepted a graceful close and is draining.| Field | Type | Required |
|---|---|---|
timestamp | datetime | Yes |
correlation_id | str | Yes |
type | Literal['session.closing'] | Yes |
data | SessionClosingData | Yes |
SessionConfigOptions
Session-config options the stream endpoint supports.| Field | Type | Required |
|---|---|---|
include | list[IncludeFlag] | No |
goal_dimensions | list[GoalDimension] | None | No |
SessionEndedData
Why the session ended.| Field | Type | Required |
|---|---|---|
reason | str | Yes |
SessionEndedEvent
Final envelope of a gracefully ended session.| Field | Type | Required |
|---|---|---|
timestamp | datetime | Yes |
correlation_id | str | Yes |
type | Literal['session.ended'] | Yes |
data | SessionEndedData | Yes |
SessionReadyData
Limits and supported options of a newly opened stream session.| Field | Type | Required |
|---|---|---|
session_idle_timeout_seconds | int | Yes |
session_max_duration_seconds | int | Yes |
max_segment_duration_seconds | float | None | No |
min_segment_size_bytes | int | Yes |
max_segment_size_bytes | int | Yes |
supported_session_config_options | SessionConfigOptions | Yes |
SessionReadyEvent
The session is accepted and ready to receive video.| Field | Type | Required |
|---|---|---|
timestamp | datetime | Yes |
correlation_id | str | Yes |
type | Literal['session.ready'] | Yes |
data | SessionReadyData | Yes |
SessionUpdatedData
The session configuration now in effect.| Field | Type | Required |
|---|---|---|
include | list[IncludeFlag] | No |
goal_dimensions | list[GoalDimension] | None | No |
SessionUpdatedEvent
Acknowledgment of a session-config update.| Field | Type | Required |
|---|---|---|
timestamp | datetime | Yes |
correlation_id | str | Yes |
type | Literal['session.updated'] | Yes |
data | SessionUpdatedData | Yes |
Signal
A detected social signal over a time range.| Field | Type | Required |
|---|---|---|
type | SignalType | Yes |
start | float | Yes |
end | float | Yes |
probability | Probability | None | No |
rationale | str | None | No |
SignalDetectedData
A newly detected signal (itsend is not known yet).
| Field | Type | Required |
|---|---|---|
signal_type | SignalType | Yes |
start | float | Yes |
probability | Probability | None | No |
rationale | str | None | No |
SignalDetectedEvent
A social signal was detected.| Field | Type | Required |
|---|---|---|
timestamp | datetime | Yes |
correlation_id | str | Yes |
type | Literal['signal.detected'] | Yes |
data | SignalDetectedData | Yes |
SignalEndedData
End time of a signal that is no longer active.| Field | Type | Required |
|---|---|---|
signal_type | SignalType | Yes |
end | float | Yes |
SignalEndedEvent
An active signal ended.| Field | Type | Required |
|---|---|---|
timestamp | datetime | Yes |
correlation_id | str | Yes |
type | Literal['signal.ended'] | Yes |
data | SignalEndedData | Yes |
SignalUpdatedData
Updated details for a signal that is still active.| Field | Type | Required |
|---|---|---|
signal_type | SignalType | Yes |
start | float | Yes |
probability | Probability | None | No |
rationale | str | None | No |
SignalUpdatedEvent
An active signal’s details changed.| Field | Type | Required |
|---|---|---|
timestamp | datetime | Yes |
correlation_id | str | Yes |
type | Literal['signal.updated'] | Yes |
data | SignalUpdatedData | Yes |
TokenResponse
Response ofPOST /v1/auth.
| Field | Type | Required |
|---|---|---|
access_token | str | Yes |
token_type | str | Yes |
expires_in | int | Yes |
scope | str | Yes |
TranscriptGeneratedEvent
The server transcribed a slice of the session’s audio.| Field | Type | Required |
|---|---|---|
timestamp | datetime | Yes |
correlation_id | str | Yes |
type | Literal['transcript.generated'] | Yes |
data | TranscriptSegment | Yes |
TranscriptSegment
One segment of a conversation transcript.| Field | Type | Required |
|---|---|---|
start | float | Yes |
end | float | Yes |
text | str | Yes |
speaker | int | No (default 0) |
UnknownEvent
A server envelope whosetype this SDK version does not know.
Newer API versions may add event types; they are surfaced as-is instead of
failing the session.
Attributes:
type: The envelope’s type discriminator.
raw: The full envelope payload as received.
| Field | Type | Required |
|---|---|---|
type | str | Yes |
raw | dict[str, Any] | Yes |
Enumerations
AnalysisGroup
Analysis track groups selectable on the real-time API.| Member | Value |
|---|---|
VIDEO | 'video' |
VISUAL | 'visual' |
AUDIO | 'audio' |
EngagementLevel
Coarse engagement state of the analyzed subject.| Member | Value |
|---|---|
ENGAGED | 'engaged' |
NEUTRAL | 'neutral' |
DISENGAGED | 'disengaged' |
GoalDimension
Interaction-goal dimensions used for feedback and conversation quality.| Member | Value |
|---|---|
CLARITY | 'clarity' |
AUTHORITY | 'authority' |
ENERGY | 'energy' |
RAPPORT | 'rapport' |
LEARNING | 'learning' |
IncludeFlag
Optional response sections selectable on upload and stream analysis.| Member | Value |
|---|---|
CONVERSATION_QUALITY_OVERALL | 'conversation_quality_overall' |
CONVERSATION_QUALITY_TIMELINE | 'conversation_quality_timeline' |
Probability
Confidence band attached to a detected signal.| Member | Value |
|---|---|
HIGH | 'high' |
MEDIUM | 'medium' |
LOW | 'low' |
RealtimeFeedbackFrequency
How often the real-time API generates feedback output.HIGH is roughly every 10 seconds of analyzed video, MEDIUM every
20 seconds, and LOW every 30 seconds.
| Member | Value |
|---|---|
HIGH | 'high' |
MEDIUM | 'medium' |
LOW | 'low' |
Scope
OAuth-style scopes accepted by the Interhuman API.| Member | Value |
|---|---|
UPLOAD | 'interhumanai.upload' |
STREAM | 'interhumanai.stream' |
REALTIME | 'interhumanai.realtime' |
SignalType
Social signals the Inter-1 model can detect.| Member | Value |
|---|---|
AGREEMENT | 'agreement' |
CONFIDENCE | 'confidence' |
CONFUSION | 'confusion' |
DISAGREEMENT | 'disagreement' |
DISENGAGEMENT | 'disengagement' |
ENGAGEMENT | 'engagement' |
FRUSTRATION | 'frustration' |
HESITATION | 'hesitation' |
INTEREST | 'interest' |
SKEPTICISM | 'skepticism' |
STRESS | 'stress' |
UNCERTAINTY | 'uncertainty' |
Exceptions
InterhumanAPIError
An error response from the Interhuman API, or a transport failure. Attributes: status: HTTP status code, or0 when the request never reached the
API (network failure).
error_id: Machine-readable error code from the response body (e.g.
ih2001), when the API supplied one.
correlation_id: Correlation id of the failed request, when supplied.
link: Documentation link for the error, when supplied.
body: The parsed JSON error body, when one was returned.
InterhumanConfigError
Raised for client-side misuse, before any network call is made. Examples: missing credentials, sending on a socket that is not open, or connecting a client that is already connected.InterhumanError
Base class for every error raised by the Interhuman SDK.Functions
http_to_ws_base_url()
https:// becomes wss:// and http:// becomes ws://; any path
is preserved and a trailing slash is trimmed.
Args:
http_base_url: The HTTP base URL to convert.
Returns:
The WebSocket base URL without a trailing slash.
parse_realtime_event()
type).
Returns:
The matching typed event, or UnknownEvent for a type
this SDK version does not know.
parse_stream_event()
type).
Returns:
The matching typed event, or UnknownEvent for a type
this SDK version does not know.
resolve_http_base_url()
http://localhost:8080). Takes
precedence over environment when provided.
environment: Named environment. Defaults to production.
Returns:
The base URL without a trailing slash.
Constants
DEFAULT_REFRESH_SKEW_SECONDS
Type:float
DEFAULT_SCOPES
Type:tuple
Environment
Type:type alias
HTTP_BASE_URLS
Type:dict
InteractionFeedback
Type:type alias
NO_GUIDANCE
Type:str
RealtimeEvent
Type:type alias
StreamEvent
Type:type alias
VideoInput
Type:type alias