Skip to main content
First-party Python SDK for the Interhuman API. Quickstart:
For a live feed, client.stream(api_version="v2") opens WS /v2/stream/analyze. Pass api_version explicitly: the default is "v1".

Clients & helpers

AuthClient

Client for the client-token endpoints (/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

The resolved HTTP base URL this client calls.

AuthClient.create_client_token()

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.revoke_client_token()

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 with access_token: your API key, or a client token your server minted, used as-is. Alternatively pass API key credentials (key_id + key_secret), exchanged for short-lived bearer tokens that are refreshed automatically. Exactly one of the two must be provided. The client exposes every public surface: auth for token endpoints, upload for complete files, and stream for live WebSocket sessions. Args: key_id: API key id (paired with key_secret). key_secret: API key secret. access_token: Your API key, or a client token, used as-is. 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()

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.stream()

Create a client for one live stream session. Each call returns a fresh, unconnected client; a client handles a single session. api_version="v1" (the default) opens WS /v1/stream/analyze, analyzed by Inter-1; api_version="v2" opens WS /v2/stream/analyze, analyzed by Inter-2. The protocol and the events are identical on both. Args: api_version: Which stream endpoint to open, "v1" or "v2". model: The Inter-2 model a "v2" session opens on (inter-2 when omitted). See ~interhumanai.StreamClient.

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.close()

Close the WebSocket immediately, discarding in-flight analysis. Args: code: WebSocket close code to send. reason: Optional close reason.

SessionSocketClient.close_info

Close code and reason once the connection has ended, else None.

SessionSocketClient.connect()

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

Whether the connection is currently open.

SessionSocketClient.request_close()

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()

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

The WebSocket URL this client connects to. Carries the endpoint’s handshake parameters and the SDK attribution query pair alongside any query parameters the configured base URL already had. The same identity also travels in the handshake’s X-Interhuman-SDK header; the two always agree.

SessionSocketClient.wait_closed()

Wait until the connection has fully closed. Returns: The session’s close code and reason.

SessionSocketClient.wait_for_session_ready()

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. The message carries the server’s own error envelope when one arrived before the close — a session the server accepts and then refuses, such as ih1003 — and the scope hint otherwise, which is the usual cause when the close explains nothing itself.

StaticTokenProvider

Token provider that always returns the same pre-issued token. Constructor

StaticTokenProvider.get_token()

Return the configured token.

StreamClient

One live session against WS /v1/stream/analyze or WS /v2/stream/analyze. Send WebM or fragmented-MP4 chunks with send_video; consume typed events with async for. api_version selects the endpoint: "v1" (the default) is analyzed by the Inter-1 model; "v2" is analyzed by an Inter-2 model. Both require the interhumanai.stream scope for the default model. The session protocol and the events are identical on both, and each names the endpoint it actually opened in the errors it raises: a v2 session reports the Inter-2 stream, a v1 session the Stream. On "v2", model names the model the session opens on (StreamModel.INTER_2 when omitted), sent as the handshake’s model query parameter. session.ready lists, under supported_session_config_options.model, the models the deployment serves that the credential may select; a later update_config(model=...) switching to one the credential lacks is answered with a non-fatal ErrorEvent (ih2003) while the session continues on its current model. 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)://. api_version: Which stream endpoint to open, "v1" or "v2". model: The Inter-2 model a "v2" session opens on. Rejected on "v1", which offers no selection. Constructor

StreamClient.api_version

The stream endpoint this client opens ("v1" or "v2").

StreamClient.model

The model a "v2" session opens on, as named at construction. None on "v1" and when the server default (inter-2) is left to apply.

StreamClient.update_config()

Replace the session configuration. Each update fully replaces the previous include and goal_dimensions; omitted options reset to their server defaults. model is session state instead: omitting it keeps the value in force, and a different value is accepted only before the first media frame. This method never sends an explicit null for it, so a selection cannot be reset through it; open a new session instead. 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. model: The Inter-2 model to analyze the session with, on api_version="v2" only. StreamModel.INTER_2 (the default) reads the video.

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.get_token()

Return a valid bearer credential, renewing it when needed.

TokenManager.invalidate()

Drop the cached token so the next call mints a fresh one.

TokenProvider

Anything that can produce a bearer credential on demand. Constructor

TokenProvider.get_token()

Return a currently valid bearer credential.

UploadClient

Client for analyzing complete files. analyze is the v1 route: the file is analyzed inside the request and the report comes back with the response. submit, get_job and wait_for_job are the v2 job routes: a file is accepted as a job, analyzed by an Inter-2 model after the response, and read back by id until it is completed or failed. 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.analyze()

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.

UploadClient.get_job()

Read a job’s current envelope from GET /v2/upload/jobs/{job_id}. Args: job_id: The job’s id, or the envelope submit returned. Returns: The envelope as it stands: result once completed, error once failed. Raises: InterhumanAPIError: ih4021 (404) when the id is unknown to this account or the job has expired, among the usual errors.

UploadClient.submit()

Submit a file to POST /v2/upload/analyze as an asynchronous job. The API validates the file and answers with the job envelope before the analysis runs. With wait_seconds above zero the request is held open for up to that long, and the envelope comes back terminal (result or error set) when the job finished in time; otherwise it comes back queued or running and wait_for_job or get_job reads it later. Pass include to have the completed job’s result carry whole-file views: the Conversation Quality Index in the sections the CQI flags name (UploadJobResult.conversation_quality), and the merged signal list for SIGNALS (UploadJobResult.signals). Without a flag the result carries no such section. For UploadModel.INTER_2 the file is an mp4, mov, avi, mkv, webm or mpeg-ts video carrying both a video and an audio track (ih5001 without picture, ih5008 without sound), with at least 3 seconds of media, at most 32 MB, and no longer than the deployment’s maximum duration (30 minutes by default; a longer file raises ih4004). The job cuts it into fixed windows and analyzes each one. Args: file: The file to analyze - raw bytes, an open binary file object, or a filesystem path. model: The Inter-2 model to analyze with. wait_seconds: How long the API may hold the request waiting for the job to finish. 0 (the default) answers at once. The deployment bounds it; a larger value raises ih4005. include: Whole-file sections the result should carry, as UploadJobIncludeFlag values: CONVERSATION_QUALITY_OVERALL and/or CONVERSATION_QUALITY_TIMELINE (the same values analyze takes, so IncludeFlag members work too) for the quality block, and SIGNALS for the signal list. Omit a flag for no such section. 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). Returns: The job envelope. Check UploadJob.status.

UploadClient.wait_for_job()

Poll a job until it is completed or failed, and return it. A terminal envelope passed in is returned at once without a request. A failed job is returned, not raised: read UploadJob.error. Args: job_id: The job’s id, or an envelope from submit or get_job. timeout: Give up after this many seconds. None waits until the job is terminal. poll_interval: Seconds between status reads. Returns: The terminal envelope. Raises: UploadJobTimeoutError: timeout elapsed first. The job keeps running; the error carries the last envelope read.

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.

ClientTokenResponse

Response of POST /v1/client_tokens.

CloseInfo

Close code and reason of a finished WebSocket session.

ConversationQuality

Conversation-quality section of an analysis result.

ConversationQualityTimelineEntry

Conversation-quality scores for one slice of the video.

ConversationQualityUpdatedData

Latest conversation-quality scores (sections follow the include flags).

ConversationQualityUpdatedEvent

New conversation-quality scores are available.

ConversationQualityValues

Conversation-quality scores (0-100; 50 means no evidence either way).

CoverageDegradedData

Ranges analyzed with partial visual coverage (billed normally). Unlike coverage.dropped, these windows were analyzed — the audio and any decodable video informed the analysis; only the visual coverage was partial (e.g. a screen share whose keyframe interval exceeds the analysis window).

CoverageDegradedEvent

One or more windows were analyzed with partial visual coverage.

CoverageDroppedData

Time ranges no analysis covers (not billed). Emitted when the analysis pipeline sheds buffered video under backpressure, and when the incoming stream itself skipped ahead — a client stall whose media never arrived while its recorder clock kept running. Either way the listed ranges were never analyzed.

CoverageDroppedEvent

Some video was dropped without being analyzed.

CoverageRange

A time range of video that was not analyzed.

EngagementStateEntry

An engagement state over a time range.

EngagementUpdatedData

The engagement state entered at start.

EngagementUpdatedEvent

The subject’s engagement state changed.

ErrorData

A session error notice (fatal errors also close the socket).

ErrorEvent

The server reported an error for this session.

Feedback

Actionable interaction feedback generated from the analysis.

FeedbackGeneratedData

Feedback text generated from the active goal dimensions.

FeedbackGeneratedEvent

Interaction feedback was generated.

NoFeedback

Explicit indication that no feedback was warranted, with the reason.

SessionClosingData

Drain window granted after a graceful close request.

SessionClosingEvent

The server accepted a graceful close and is draining.

SessionConfigOptions

Session-config options the stream endpoint supports. Attributes: include: The conversation-quality sections a config may include. goal_dimensions: The goal dimensions a config may set, or None when feedback is disabled. model: The models the deployment serves on WS /v2/stream/analyze that the credential may select; None on WS /v1/stream/analyze, which offers no selection.

SessionEndedData

Why the session ended.

SessionEndedEvent

Final envelope of a gracefully ended session.

SessionReadyData

Limits and supported options of a newly opened stream session.

SessionReadyEvent

The session is accepted and ready to receive video.

SessionUpdatedData

The session configuration now in effect. Attributes: include: The conversation-quality sections in force. goal_dimensions: The goal dimensions in force, or None when feedback is disabled. model: The model analyzing the session on WS /v2/stream/analyze; None on WS /v1/stream/analyze.

SessionUpdatedEvent

Acknowledgment of a session-config update.

Signal

A detected social signal over a time range. modality names the analysis modalities that detected this signal. When several tracks detect the same signal, every contributing modality is included.

SignalDetectedData

A newly detected signal (its end is not known yet). modality names the analyses whose evidence produced the signal. It is sent on WS /v1/stream/analyze, where it is ["video"], and is None on WS /v2/stream/analyze, which omits it because the session’s model names the evidence instead.

SignalDetectedEvent

A social signal was detected.

SignalEndedData

End time of a signal that is no longer active.

SignalEndedEvent

An active signal ended.

SignalUpdatedData

Updated details for a signal that is still active. modality is sent on WS /v1/stream/analyze, where a change to it — the set of analyses reporting the signal — is one of the things that emits signal.updated. It is None on WS /v2/stream/analyze, which omits it.

SignalUpdatedEvent

An active signal’s details changed.

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.

UploadJob

The job envelope both v2 upload routes answer with. Returned by POST /v2/upload/analyze and GET /v2/upload/jobs/{job_id} alike. result is set only when status is COMPLETED; error only when it is FAILED. status_url is the status resource’s path, relative to the API base URL.

UploadJobConversationQuality

The Conversation Quality Index of a completed upload job. Scored once over the whole file from every window’s signals and engagement. Each section is set only when ~interhumanai.UploadClient.submit asked for it with the matching IncludeFlag: overall for CONVERSATION_QUALITY_OVERALL, timeline for CONVERSATION_QUALITY_TIMELINE. A requested section is present even when no signal was detected; every dimension then reads the neutral 50.

UploadJobError

Why an upload job failed, in the API’s standard error-body shape.

UploadJobResult

The result of a completed upload job: one entry per analyzed window. signals is every window’s signals as one list over the whole file, in chronological order, merged by the same rules as ~interhumanai.UploadClient.analyze and with no modality: signals of the same type in adjacent windows become one span, which keeps the highest probability and that signal’s rationale. It is set only when the submit passed UploadJobIncludeFlag.SIGNALS, and is then an empty list when nothing was detected; windows are unchanged either way. conversation_quality is present only when the submit passed at least one Conversation Quality Index flag, and carries the sections those flags named.

UploadJobSignal

A social signal detected in one window of an upload job. It carries the window’s span as its start and end. Unlike the v1 Signal, it has no modality: the job’s model names the evidence the model read.

UploadJobWindow

The analysis of one fixed-length window of an upload job’s file. signals carry the window’s span as their start and end.

Enumerations

EngagementLevel

Coarse engagement state of the analyzed subject.

GoalDimension

Interaction-goal dimensions used for feedback and conversation quality.

IncludeFlag

Optional response sections selectable on upload and stream analysis.

Probability

Confidence band attached to a detected signal.

Scope

OAuth-style scopes accepted by the Interhuman API. A scope names one endpoint family across every API version. UPLOAD covers POST /v1/upload/analyze and POST /v2/upload/analyze with model="inter-2", and reads the account’s jobs at GET /v2/upload/jobs/{job_id}; STREAM covers WS /v1/stream/analyze and WS /v2/stream/analyze with model="inter-2". No scope implies another. The token response’s scope is authoritative.

SignalType

Social signals the Interhuman API can detect.

StreamModel

Inter-2 models a WS /v2/stream/analyze session can select. INTER_2 (the default) reads the video. WS /v1/stream/analyze offers no selection and rejects any value.

UploadJobIncludeFlag

Whole-file sections a POST /v2/upload/analyze job’s result can carry. The two IncludeFlag Conversation Quality Index sections, plus SIGNALS for the whole-file signal list (UploadJobResult.signals). SIGNALS is a v2 upload option only; ~interhumanai.UploadClient.analyze and the stream do not take it.

UploadJobStatus

Lifecycle of a POST /v2/upload/analyze job. QUEUED and RUNNING are transient; COMPLETED and FAILED are terminal, and the job stays readable until its expires_at.

UploadModel

Inter-2 models a POST /v2/upload/analyze job can name. INTER_2 reads a video (picture and sound together).

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, 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.

UploadJobTimeoutError

An upload job did not reach a terminal state within the wait the caller allowed. Raised by ~interhumanai.UploadClient.wait_for_job. The job itself is unaffected — it keeps running, and job is the last envelope read, so the caller can keep polling with its job_id.

Functions

http_to_ws_base_url()

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_stream_event()

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()

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.

sdk_header_value()

Return the X-Interhuman-SDK value: python/<version>.

Constants

DEFAULT_JOB_POLL_INTERVAL_SECONDS

Type: float

DEFAULT_REFRESH_SKEW_SECONDS

Type: float

DEFAULT_SCOPES

Type: tuple

Environment

Type: type alias

HTTP_BASE_URLS

Type: dict

InteractionFeedback

Type: type alias

SDK_HEADER_NAME

Type: str

SDK_NAME

Type: str

STREAM_ENDPOINT_PATHS

Type: dict

StreamApiVersion

Type: type alias

StreamEvent

Type: type alias

VideoInput

Type: type alias