Skip to main content
First-party Python SDK for the Interhuman API. Quickstart:
import asyncio
from interhumanai import InterhumanClient

async def main() -> None:
    client = InterhumanClient(key_id="...", key_secret="...")
    result = await client.upload.analyze("meeting.mp4")
    for signal in result.signals:
        print(signal.type.value, signal.start, signal.end)

asyncio.run(main())

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(*, environment: Optional[Literal['production', 'staging']] = None, base_url: str | None = None, http_client: httpx.AsyncClient | None = None) -> None

AuthClient.base_url

@property
def base_url(self) -> str
The resolved HTTP base URL this client calls.

AuthClient.create_client_token()

async def create_client_token(self, *, api_key: str, scopes: collections.abc.Sequence[Scope | str] | None = None, expires_in: int | None = None, max_duration_seconds: int | None = None, max_bytes: int | None = None, max_concurrent: int | None = None, max_video_seconds: int | None = None, allowed_origins: collections.abc.Sequence[str] | None = None) -> ClientTokenResponse
Mint a short-lived, capped client token for direct end-user use. Call this from a trusted server: the full API key travels in the request body. Omitted options use the server defaults (scope 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()

async def create_token(self, *, key_id: str, key_secret: str, scopes: collections.abc.Sequence[Scope | str]) -> TokenResponse
Exchange API key credentials for a short-lived bearer access token. Args: key_id: The API key id. key_secret: The API key secret. scopes: Scopes to request; must be non-empty and held by the key. Returns: The minted token, its lifetime, and the granted scopes.

AuthClient.revoke_client_token()

async def revoke_client_token(self, *, api_key: str, token: str) -> None
Revoke a previously minted client token. Revoking an already-expired token is a no-op and also succeeds. Args: api_key: The API key that minted the token. token: The client token to revoke.

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(*, key_id: str | None = None, key_secret: str | None = None, access_token: str | None = None, scopes: collections.abc.Sequence[Scope | str] | None = None, environment: Optional[Literal['production', 'staging']] = None, base_url: str | None = None, http_client: httpx.AsyncClient | None = None, refresh_skew_seconds: float = 30.0) -> None

InterhumanClient.get_token()

async def get_token(self) -> str
Return the bearer token the client is currently using. With managed credentials this mints or refreshes as needed; with a pre-issued access_token it returns that token unchanged.

InterhumanClient.realtime()

def realtime(self) -> RealtimeClient
Create a client for one WS /v0/realtime/analyze session. Each call returns a fresh, unconnected client; a client handles a single session.

InterhumanClient.stream()

def stream(self) -> StreamClient
Create a client for one WS /v1/stream/analyze session. Each call returns a fresh, unconnected client; a client handles a single session.

RealtimeClient

One live session against WS /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()

async def send_transcript(self, transcript: collections.abc.Sequence[TranscriptSegment]) -> None
Send the latest client-side transcript of the conversation. Each call fully replaces any previously sent transcript; the latest transcript is rendered into subsequent feedback output. Args: transcript: Ordered transcript segments (speaker ids are zero-based).

RealtimeClient.update_config()

async def update_config(self, *, analysis_groups: collections.abc.Sequence[AnalysisGroup | str] | None = None, realtime_feedback_frequency: RealtimeFeedbackFrequency | str | None = None, realtime_feedback_instructions: str | None = None, goal_dimensions: collections.abc.Sequence[GoalDimension | str] | None = None) -> None
Replace the session configuration. Each update fully replaces the previous configuration; omitted options reset to their server defaults. The server acknowledges with a 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 with connect (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(*, token_provider: TokenProvider, environment: Optional[Literal['production', 'staging']] = None, base_url: str | None = None) -> None

SessionSocketClient.close()

async def close(self, code: int = 1000, reason: str = '') -> None
Close the WebSocket immediately, discarding in-flight analysis. Args: code: WebSocket close code to send. reason: Optional close reason.

SessionSocketClient.close_info

@property
def close_info(self) -> CloseInfo | None
Close code and reason once the connection has ended, else None.

SessionSocketClient.connect()

async def connect(self) -> 'SessionSocketClient[EventT]'
Open the WebSocket connection and start receiving events. Returns: This client, for chaining. Raises: InterhumanConfigError: If the client was already connected. InterhumanError: If the handshake fails (bad credentials or scope, unreachable host).

SessionSocketClient.is_open

@property
def is_open(self) -> bool
Whether the connection is currently open.

SessionSocketClient.request_close()

async def request_close(self) -> None
Ask the server to drain in-flight analysis and end the session. The server acknowledges with 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()

async def send_video(self, chunk: bytes | bytearray | memoryview) -> None
Send one binary video chunk. The first chunk must carry the container’s init header; later chunks are continuation fragments of the same WebM or fragmented-MP4 stream. The SDK does not enforce a chunk size; the server rejects chunks above its limit (32 MB by default, reported in session.ready as max_segment_size_bytes) with an ih6002 error. Args: chunk: The raw video bytes to send.

SessionSocketClient.url

@property
def url(self) -> str
The WebSocket URL this client connects to.

SessionSocketClient.wait_closed()

async def wait_closed(self) -> CloseInfo
Wait until the connection has fully closed. Returns: The session’s close code and reason.

SessionSocketClient.wait_for_session_ready()

async def wait_for_session_ready(self) -> EventT
Wait for the server’s 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. Constructor
StaticTokenProvider(token: str) -> None

StaticTokenProvider.get_token()

async def get_token(self) -> str
Return the configured token.

StreamClient

One live session against WS /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()

async def update_config(self, *, include: collections.abc.Sequence[IncludeFlag | str] | None = None, goal_dimensions: collections.abc.Sequence[GoalDimension | str] | None = None) -> None
Replace the session configuration. Each update fully replaces the previous configuration; omitted options reset to their server defaults. The server acknowledges with a 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 until expires_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(*, auth_client: AuthClient, key_id: str, key_secret: str, scopes: collections.abc.Sequence[Scope | str] = (<Scope.UPLOAD: 'interhumanai.upload'>, <Scope.STREAM: 'interhumanai.stream'>), refresh_skew_seconds: float = 30.0, clock: Callable[[], float] = <built-in function monotonic>) -> None

TokenManager.get_token()

async def get_token(self) -> str
Return a valid access token, minting or refreshing when needed.

TokenManager.invalidate()

def invalidate(self) -> None
Drop the cached token so the next call mints a fresh one.

TokenProvider

Anything that can produce a bearer access token on demand. Constructor
TokenProvider(*args, **kwargs)

TokenProvider.get_token()

async def get_token(self) -> str
Return a currently valid bearer access token.

UploadClient

Client for analyzing complete video files. Args: token_provider: Source of bearer tokens for authentication. environment: Named environment to call. Defaults to production. base_url: Explicit base URL override. http_client: Optional shared httpx.AsyncClient. When omitted, a client is created per request. Constructor
UploadClient(*, token_provider: TokenProvider, environment: Optional[Literal['production', 'staging']] = None, base_url: str | None = None, http_client: httpx.AsyncClient | None = None) -> None

UploadClient.analyze()

async def analyze(self, file: Union[bytes, bytearray, memoryview, IO[bytes], str, os.PathLike[str]], *, filename: str | None = None, content_type: str | None = None, include: collections.abc.Sequence[IncludeFlag | str] | None = None, goal_dimensions: collections.abc.Sequence[GoalDimension | str] | None = None, conversation_context: str | None = None) -> AnalysisResult
Analyze a complete video file and return the detected signals. The video must be at least 3 seconds long and at most 32 MB, in one of the supported containers (mp4, avi, mov, mkv, mpeg-ts, webm). Args: file: The video to analyze - raw bytes, an open binary file object, or a filesystem path. filename: Filename reported to the API. Defaults to the path or file object’s name, else 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 of POST /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.
FieldTypeRequired
signalslist[Signal]No
engagement_statelist[EngagementStateEntry]No
feedbackOptional[Feedback | NoFeedback]No
conversation_qualityConversationQuality | NoneNo

ClientTokenResponse

Response of POST /v1/client_tokens.
FieldTypeRequired
access_tokenstrYes
token_typestrYes
expires_inintYes
scopestrYes
max_duration_secondsint | NoneNo
max_bytesint | NoneNo
max_concurrentint | NoneNo
max_video_secondsint | NoneNo
allowed_originslist[str] | NoneNo

CloseInfo

Close code and reason of a finished WebSocket session.
FieldTypeRequired
codeintYes
reasonstrYes

ConversationQuality

Conversation-quality section of an analysis result.
FieldTypeRequired
overallConversationQualityValuesYes
timelinelist[ConversationQualityTimelineEntry]No

ConversationQualityTimelineEntry

Conversation-quality scores for one slice of the video.
FieldTypeRequired
startfloatYes
endfloatYes
valuesConversationQualityValuesYes

ConversationQualityUpdatedData

Latest conversation-quality scores (sections follow the include flags).
FieldTypeRequired
overallConversationQualityValues | NoneNo
timelinelist[ConversationQualityTimelineEntry] | NoneNo

ConversationQualityUpdatedEvent

New conversation-quality scores are available.
FieldTypeRequired
timestampdatetimeYes
correlation_idstrYes
typeLiteral['conversation_quality.updated']Yes
dataConversationQualityUpdatedDataYes

ConversationQualityValues

Conversation-quality scores (0-100; 50 means no evidence either way).
FieldTypeRequired
quality_indexfloatYes
clarityfloatYes
authorityfloatYes
energyfloatYes
rapportfloatYes
learningfloatYes

CoverageDroppedData

Video ranges dropped under backpressure (not billed).
FieldTypeRequired
rangeslist[CoverageRange]No

CoverageDroppedEvent

Some video was dropped without being analyzed.
FieldTypeRequired
timestampdatetimeYes
correlation_idstrYes
typeLiteral['coverage.dropped']Yes
dataCoverageDroppedDataYes

CoverageRange

A time range of video that was not analyzed.
FieldTypeRequired
startfloatYes
endfloatYes

EngagementStateEntry

An engagement state over a time range.
FieldTypeRequired
stateEngagementLevelYes
startfloatYes
endfloatYes

EngagementUpdatedData

The engagement state entered at start.
FieldTypeRequired
stateEngagementLevelYes
startfloatYes

EngagementUpdatedEvent

The subject’s engagement state changed.
FieldTypeRequired
timestampdatetimeYes
correlation_idstrYes
typeLiteral['engagement.updated']Yes
dataEngagementUpdatedDataYes

ErrorData

A session error notice (fatal errors also close the socket).
FieldTypeRequired
codestrYes
messagestrYes
linkstr | NoneNo
segmentint | NoneNo

ErrorEvent

The server reported an error for this session.
FieldTypeRequired
timestampdatetimeYes
correlation_idstrYes
typeLiteral['error']Yes
dataErrorDataYes

Feedback

Actionable interaction feedback generated from the analysis.
FieldTypeRequired
typeLiteral['feedback']No (default 'feedback')
messagestrYes
active_dimensionslist[GoalDimension]No
primary_signalSignalType | NoneNo

FeedbackGeneratedData

Feedback text generated from the active goal dimensions.
FieldTypeRequired
feedbackstrYes

FeedbackGeneratedEvent

Interaction feedback was generated.
FieldTypeRequired
timestampdatetimeYes
correlation_idstrYes
typeLiteral['feedback.generated']Yes
dataFeedbackGeneratedDataYes

NoFeedback

Explicit indication that no feedback was warranted, with the reason.
FieldTypeRequired
typeLiteral['no_feedback']No (default 'no_feedback')
reasonstrYes

RealtimeFeedbackGeneratedData

Generated guidance for the analyzed window. text is the literal NO_GUIDANCE when the model had nothing to suggest for this window.
FieldTypeRequired
textstrYes
startfloatYes
endfloatYes

RealtimeFeedbackGeneratedEvent

New feedback output is available.
FieldTypeRequired
timestampdatetimeYes
correlation_idstrYes
typeLiteral['realtime_feedback.generated']Yes
dataRealtimeFeedbackGeneratedDataYes

RealtimeSessionConfigOptions

Session-config options the real-time endpoint supports.
FieldTypeRequired
realtime_feedback_instructionsstrYes
realtime_feedback_frequencylist[RealtimeFeedbackFrequency]Yes
analysis_groupslist[AnalysisGroup]Yes

RealtimeSessionReadyData

Limits and supported options of a newly opened real-time session.
FieldTypeRequired
session_idle_timeout_secondsintYes
session_max_duration_secondsintYes
max_segment_duration_secondsfloat | NoneNo
min_segment_size_bytesintYes
max_segment_size_bytesintYes
supported_session_config_optionsRealtimeSessionConfigOptionsYes

RealtimeSessionReadyEvent

The session is accepted and ready to receive video.
FieldTypeRequired
timestampdatetimeYes
correlation_idstrYes
typeLiteral['session.ready']Yes
dataRealtimeSessionReadyDataYes

RealtimeSessionUpdatedData

The real-time session configuration now in effect.
FieldTypeRequired
realtime_feedback_instructionsstr | NoneNo
realtime_feedback_frequencyRealtimeFeedbackFrequency | NoneNo
analysis_groupslist[AnalysisGroup]Yes

RealtimeSessionUpdatedEvent

Acknowledgment of a session-config update.
FieldTypeRequired
timestampdatetimeYes
correlation_idstrYes
typeLiteral['session.updated']Yes
dataRealtimeSessionUpdatedDataYes

SessionClosingData

Drain window granted after a graceful close request.
FieldTypeRequired
max_drain_secondsintYes

SessionClosingEvent

The server accepted a graceful close and is draining.
FieldTypeRequired
timestampdatetimeYes
correlation_idstrYes
typeLiteral['session.closing']Yes
dataSessionClosingDataYes

SessionConfigOptions

Session-config options the stream endpoint supports.
FieldTypeRequired
includelist[IncludeFlag]No
goal_dimensionslist[GoalDimension] | NoneNo

SessionEndedData

Why the session ended.
FieldTypeRequired
reasonstrYes

SessionEndedEvent

Final envelope of a gracefully ended session.
FieldTypeRequired
timestampdatetimeYes
correlation_idstrYes
typeLiteral['session.ended']Yes
dataSessionEndedDataYes

SessionReadyData

Limits and supported options of a newly opened stream session.
FieldTypeRequired
session_idle_timeout_secondsintYes
session_max_duration_secondsintYes
max_segment_duration_secondsfloat | NoneNo
min_segment_size_bytesintYes
max_segment_size_bytesintYes
supported_session_config_optionsSessionConfigOptionsYes

SessionReadyEvent

The session is accepted and ready to receive video.
FieldTypeRequired
timestampdatetimeYes
correlation_idstrYes
typeLiteral['session.ready']Yes
dataSessionReadyDataYes

SessionUpdatedData

The session configuration now in effect.
FieldTypeRequired
includelist[IncludeFlag]No
goal_dimensionslist[GoalDimension] | NoneNo

SessionUpdatedEvent

Acknowledgment of a session-config update.
FieldTypeRequired
timestampdatetimeYes
correlation_idstrYes
typeLiteral['session.updated']Yes
dataSessionUpdatedDataYes

Signal

A detected social signal over a time range.
FieldTypeRequired
typeSignalTypeYes
startfloatYes
endfloatYes
probabilityProbability | NoneNo
rationalestr | NoneNo

SignalDetectedData

A newly detected signal (its end is not known yet).
FieldTypeRequired
signal_typeSignalTypeYes
startfloatYes
probabilityProbability | NoneNo
rationalestr | NoneNo

SignalDetectedEvent

A social signal was detected.
FieldTypeRequired
timestampdatetimeYes
correlation_idstrYes
typeLiteral['signal.detected']Yes
dataSignalDetectedDataYes

SignalEndedData

End time of a signal that is no longer active.
FieldTypeRequired
signal_typeSignalTypeYes
endfloatYes

SignalEndedEvent

An active signal ended.
FieldTypeRequired
timestampdatetimeYes
correlation_idstrYes
typeLiteral['signal.ended']Yes
dataSignalEndedDataYes

SignalUpdatedData

Updated details for a signal that is still active.
FieldTypeRequired
signal_typeSignalTypeYes
startfloatYes
probabilityProbability | NoneNo
rationalestr | NoneNo

SignalUpdatedEvent

An active signal’s details changed.
FieldTypeRequired
timestampdatetimeYes
correlation_idstrYes
typeLiteral['signal.updated']Yes
dataSignalUpdatedDataYes

TokenResponse

Response of POST /v1/auth.
FieldTypeRequired
access_tokenstrYes
token_typestrYes
expires_inintYes
scopestrYes

TranscriptGeneratedEvent

The server transcribed a slice of the session’s audio.
FieldTypeRequired
timestampdatetimeYes
correlation_idstrYes
typeLiteral['transcript.generated']Yes
dataTranscriptSegmentYes

TranscriptSegment

One segment of a conversation transcript.
FieldTypeRequired
startfloatYes
endfloatYes
textstrYes
speakerintNo (default 0)

UnknownEvent

A server envelope whose type 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.
FieldTypeRequired
typestrYes
rawdict[str, Any]Yes

Enumerations

AnalysisGroup

Analysis track groups selectable on the real-time API.
MemberValue
VIDEO'video'
VISUAL'visual'
AUDIO'audio'

EngagementLevel

Coarse engagement state of the analyzed subject.
MemberValue
ENGAGED'engaged'
NEUTRAL'neutral'
DISENGAGED'disengaged'

GoalDimension

Interaction-goal dimensions used for feedback and conversation quality.
MemberValue
CLARITY'clarity'
AUTHORITY'authority'
ENERGY'energy'
RAPPORT'rapport'
LEARNING'learning'

IncludeFlag

Optional response sections selectable on upload and stream analysis.
MemberValue
CONVERSATION_QUALITY_OVERALL'conversation_quality_overall'
CONVERSATION_QUALITY_TIMELINE'conversation_quality_timeline'

Probability

Confidence band attached to a detected signal.
MemberValue
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.
MemberValue
HIGH'high'
MEDIUM'medium'
LOW'low'

Scope

OAuth-style scopes accepted by the Interhuman API.
MemberValue
UPLOAD'interhumanai.upload'
STREAM'interhumanai.stream'
REALTIME'interhumanai.realtime'

SignalType

Social signals the Inter-1 model can detect.
MemberValue
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, or 0 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()

def http_to_ws_base_url(http_base_url: str) -> str
Derive the WebSocket base URL from an HTTP 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()

def parse_realtime_event(payload: dict[str, Any]) -> Union[RealtimeSessionReadyEvent, RealtimeSessionUpdatedEvent, SessionClosingEvent, SessionEndedEvent, SignalDetectedEvent, SignalUpdatedEvent, SignalEndedEvent, TranscriptGeneratedEvent, RealtimeFeedbackGeneratedEvent, CoverageDroppedEvent, ErrorEvent, UnknownEvent]
Parse one real-time envelope into its typed event model. Args: payload: The decoded JSON envelope (must carry a string type). Returns: The matching typed event, or UnknownEvent for a type this SDK version does not know.

parse_stream_event()

def parse_stream_event(payload: dict[str, Any]) -> Union[SessionReadyEvent, SessionUpdatedEvent, SessionClosingEvent, SessionEndedEvent, SignalDetectedEvent, SignalUpdatedEvent, SignalEndedEvent, EngagementUpdatedEvent, ConversationQualityUpdatedEvent, FeedbackGeneratedEvent, CoverageDroppedEvent, ErrorEvent, UnknownEvent]
Parse one stream envelope into its typed event model. Args: payload: The decoded JSON envelope (must carry a string type). Returns: The matching typed event, or UnknownEvent for a type this SDK version does not know.

resolve_http_base_url()

def resolve_http_base_url(*, base_url: str | None = None, environment: Optional[Literal['production', 'staging']] = None) -> str
Resolve the HTTP base URL from an explicit override or a named environment. Args: base_url: Explicit base URL (e.g. 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_REFRESH_SKEW_SECONDS = 30.0

DEFAULT_SCOPES

Type: tuple
DEFAULT_SCOPES = (<Scope.UPLOAD: 'interhumanai.upload'>, <Scope.STREAM: 'interhumanai.stream'>)

Environment

Type: type alias
Environment = Literal['production', 'staging']

HTTP_BASE_URLS

Type: dict
HTTP_BASE_URLS = {'production': 'https://api.interhuman.ai', 'staging': 'https://staging-api.interhuman.ai'}

InteractionFeedback

Type: type alias
InteractionFeedback = Feedback | NoFeedback

NO_GUIDANCE

Type: str
NO_GUIDANCE = 'NO_GUIDANCE'

RealtimeEvent

Type: type alias
RealtimeEvent = Union[RealtimeSessionReadyEvent, RealtimeSessionUpdatedEvent, SessionClosingEvent, SessionEndedEvent, SignalDetectedEvent, SignalUpdatedEvent, SignalEndedEvent, TranscriptGeneratedEvent, RealtimeFeedbackGeneratedEvent, CoverageDroppedEvent, ErrorEvent, UnknownEvent]

StreamEvent

Type: type alias
StreamEvent = Union[SessionReadyEvent, SessionUpdatedEvent, SessionClosingEvent, SessionEndedEvent, SignalDetectedEvent, SignalUpdatedEvent, SignalEndedEvent, EngagementUpdatedEvent, ConversationQualityUpdatedEvent, FeedbackGeneratedEvent, CoverageDroppedEvent, ErrorEvent, UnknownEvent]

VideoInput

Type: type alias
VideoInput = Union[bytes, bytearray, memoryview, IO[bytes], str, os.PathLike[str]]