SDKs

Connect from any language.

All client SDKs speak the same WHIP protocol and DataChannel event format. Plugin SDKs handle the JSON-RPC protocol so you can focus on your tool logic.

Client SDKs

One protocol, five languages. Use TypeScript for browser apps, React Native for mobile, Go or Rust for CLI tools, Python for notebooks and automation. Drop-in connection in under 10 lines of code.

TypeScript

@streamcore/js-sdk

For browsers, React, Next.js, and Node.js. Handles WHIP negotiation, DataChannel events, and media stream management.

Install

npm install @streamcore/js-sdk

Usage

import { StreamCoreAIClient } from "@streamcore/js-sdk";

const client = new StreamCoreAIClient(
  { whipUrl: "http://localhost:8080/whip" },
  {
    onTranscript: (entry) => console.log(entry),
    onStatusChange: (s) => console.log(s),
  }
);
await client.connect();

Go

github.com/streamcoreai/go-sdk

For CLI tools, backend services, and server-to-server integrations. Native WebRTC via Pion.

Install

go get github.com/streamcoreai/go-sdk

Usage

import streamcoreai "github.com/streamcoreai/go-sdk"

client := streamcoreai.NewClient(
    streamcoreai.Config{WHIPEndpoint: "http://localhost:8080/whip"},
    streamcoreai.EventHandler{
        OnTranscript: func(e streamcoreai.TranscriptEntry, all []streamcoreai.TranscriptEntry) {
            fmt.Println(e.Role, e.Text)
        },
    },
)
client.Connect(ctx)

Python

streamcore

For notebooks, automation scripts, and Python applications. Async-first with callback support.

Install

pip install streamcore

Usage

import asyncio
import streamcore

async def main():
    client = streamcore.Client(
        config=streamcore.Config(whip_endpoint="http://localhost:8080/whip"),
        events=streamcore.EventHandler(
            on_transcript=lambda entry, _: print(f"[{entry.role}] {entry.text}"),
        ),
    )
    await client.connect()
    # ... send/receive audio ...
    await client.disconnect()

asyncio.run(main())

Rust

streamcore-rust-sdk

For high-performance CLI tools and embedded systems. Native WebRTC via webrtc-rs.

Install

cargo add streamcore-rust-sdk

Usage

use streamcore_rust_sdk::{Client, Config, EventHandler};

let client = Client::new(
    Config {
        whip_endpoint: "http://localhost:8080/whip".into(),
        ..Default::default()
    },
    EventHandler {
        on_transcript: Some(Box::new(|e, _all| {
            println!("{}: {}", e.role, e.text);
        })),
        ..Default::default()
    },
);
client.connect().await?;

React NativeComing soon

@streamcore/react-native-sdk

For Expo and bare React Native apps. A hook wrapper over the same client, built on react-native-webrtc. Written and working, publication pending — until it lands, vendor the source or wrap the browser SDK in a WebView.

Install

# not on npm yet — vendor the source from the monorepo

Usage

import { useStreamCoreAI } from '@streamcore/react-native-sdk';

const {
  status, transcript, audioLevel, isMuted,
  connect, disconnect, toggleMute, error,
} = useStreamCoreAI({
  whipUrl: 'https://agent.example.com/whip',
  // tokenUrl: 'https://api.example.com/agent-token',  // optional short-lived token
});

WHIP + DataChannel Protocol

All SDKs use the same underlying protocol. WHIP (RFC 9725) handles signaling with a single HTTP POST. A WebRTC DataChannel carries structured events bidirectionally.

DataChannel Events

  • transcript — Real-time speech-to-text results (partial and final)
  • response — LLM response text as it streams
  • error — Error messages from the server
  • timing — Pipeline latency events (LLM first token, TTS first byte)

Event format

// Transcript (partial or final)
{"type": "transcript", "text": "What's the weather in Tokyo?", "final": true}

// LLM response
{"type": "response", "text": "Let me check that for you."}

// Timing metrics
{"type": "timing", "stage": "llm_first_token", "ms": 312}

// Error
{"type": "error", "message": "TTS provider timeout"}

Connection Lifecycle

  1. 1. Client creates SDP offer (audio sendrecv, datachannel for events)
  2. 2. Client gathers ICE candidates
  3. 3. Client POSTs SDP offer to POST /whip
  4. 4. Server responds with 201 Created, SDP answer, and Location: /whip/{sessionId}
  5. 5. ICE handshake completes, bidirectional RTP starts flowing
  6. 6. DataChannel opens for transcript/response events
  7. 7. Client sends DELETE /whip/{sessionId} to tear down

Plugin SDKs

Plugin SDKs handle the JSON-RPC protocol, initialization, and logging. You just implement the execute handler.

Python Plugin SDK

streamcore-plugin

Install

pip install streamcore-plugin

Usage

from streamcoreai_plugin import StreamCoreAIPlugin

plugin = StreamCoreAIPlugin()

@plugin.on_execute
def handle(params):
    return f"Result for {params['query']}"

@plugin.on_initialize
def init():
    plugin.log("Plugin ready")

plugin.run()

TypeScript Plugin SDK

@streamcore/plugin

Install

npm install @streamcore/plugin

Usage

import { StreamCoreAIPlugin } from '@streamcore/plugin';

const plugin = new StreamCoreAIPlugin();

plugin.onExecute(async (params) => {
  return `Result for ${params.query}`;
});

plugin.onInitialize(() => {
  plugin.log("Plugin ready");
});

plugin.run();