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, four languages. Use TypeScript for browser apps, 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

streamcoreai-sdk

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

Install

pip install streamcoreai-sdk

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?;

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