@corti/sdk package exports four main APIs:
| Export | Import | Purpose |
|---|---|---|
CortiClient | import { CortiClient } from "@corti/sdk" | Full API client with all resource groups, authentication, and WebSockets |
CortiAuth | import { CortiAuth } from "@corti/sdk" | Standalone authentication client for token management and OAuth flows |
CortiWebSocketProxyClient | import { CortiWebSocketProxyClient } from "@corti/sdk" | WebSocket-only proxy client for stream and transcribe |
| Utilities | import { ... } from "@corti/sdk/utils" | Token decoding, environment resolution, and PKCE helpers |
CortiClient
The main client for all Corti API operations.Constructor options
JavaScript
import { CortiClient } from "@corti/sdk";
const client = new CortiClient({
environment: "<eu-or-us>",
tenantName: "<your-tenant-name>",
auth: { ... }, // see Authentication Guide
// Optional
headers: { "X-Custom": "value" }, // headers sent with every request
timeoutInSeconds: 60, // default request timeout
maxRetries: 2, // default retry count
fetcher: customFetchFn, // custom fetch implementation
logging: { ... }, // logging configuration
withCredentials: false, // include cookies in CORS requests
encodeHeadersAsWsProtocols: false, // encode auth headers as WS subprotocols
analytics: { app: "docs-example" }, // extra x-corti-analytics keys
});
| Option | Type | Default | Description |
|---|---|---|---|
environment | CortiEnvironment | CortiEnvironmentUrls | string | Required | API region or custom URLs |
tenantName | string | Required | Your Corti tenant name |
auth | CortiClient.Auth | Required | Authentication configuration (all flows) |
headers | Record<string, string> | undefined | Headers sent with every request |
timeoutInSeconds | number | 60 | Default request timeout |
maxRetries | number | 2 | Default retry count |
fetcher | (url, init) => Promise<Response> | undefined | Custom fetch implementation |
logging | { level, logger, silent } | { silent: true } | Logging config |
withCredentials | boolean | false | Include cookies in CORS requests |
encodeHeadersAsWsProtocols | boolean | false | Encode auth as WS subprotocols (for restrictive gateways) |
baseUrl | string | undefined | Route all traffic through a proxy |
analytics | Record<string, string> | undefined | Extra keys on x-corti-analytics. Reserved keys sdk_type and sdk_version are set by the SDK. |
Request options
Every HTTP method accepts an optional request options object as the last argument:JavaScript
const response = await client.interactions.create(
{ encounter: { identifier: "id", status: "planned", type: "first_consultation" } },
{
timeoutInSeconds: 30,
maxRetries: 3,
abortSignal: controller.signal,
headers: { "X-Custom-Header": "value" },
queryParams: { customKey: "customValue" },
},
);
| Option | Type | Description |
|---|---|---|
timeoutInSeconds | number | Override the default 60s timeout |
maxRetries | number | Override the default 2 retries |
abortSignal | AbortSignal | Cancel the request |
headers | Record<string, string> | Additional HTTP headers |
queryParams | Record<string, string> | Additional query string parameters |
Client methods
| Method | Returns | Description |
|---|---|---|
getEnvironmentUrls() | Promise<CortiEnvironmentUrls> | REST and WebSocket base URLs for the configured environment (base, wss, login, agents) |
Resource groups
The client exposes the following resource groups as properties:| Group | Description | API endpoints |
|---|---|---|
client.interactions | Manage patient encounters and interaction sessions | Interactions API |
client.recordings | Upload and retrieve audio recordings for interactions | Recordings API |
client.languages | List available languages and enabled endpoint details | Languages |
client.transcripts | Create and retrieve transcriptions of recordings | Transcripts API |
client.documents | Generate a clinical document from templates or dynamic definitions; list/get/update/delete persisted guided documents | Documents |
client.documents.templates | Create, version, and publish guided document templates | Guided Templates |
client.documents.sections | Create, version, and publish guided document sections | Section Creation |
client.documents.classic | Interaction-scoped document CRUD (deprecated) | Documents Classic |
client.facts | Extract and manage structured clinical facts | Facts API |
client.templates | List and retrieve classic document generation templates | Templates API |
client.codes | Predict medical codes from clinical data | Codes API |
client.agents | Create and interact with AI agents (v1, deprecated) | Agentic APIs v1 |
client.agentic | Agents API v2 (client.agentic.agents, contexts, registry) | Agentic APIs v2 |
client.stream | Real-time WebSocket streaming (transcription + facts) | Stream API |
client.transcribe | Real-time WebSocket speech-to-text (standalone) | Transcribe API |
client.auth | OAuth token management and authorization URLs | Auth API |
Interactions
Manage interaction sessions that group recordings, transcripts, documents, and facts together.// List interactions (paginated)
const page = await client.interactions.list({ limit: 10 });
for await (const interaction of page) {
console.log(interaction.interactionId);
}
// Create a new interaction
const { interactionId } = await client.interactions.create({
encounter: {
identifier: "my-encounter-id",
status: "planned",
type: "first_consultation",
},
});
// Get a specific interaction
const interaction = await client.interactions.get(interactionId);
// Update an interaction
await client.interactions.update(interactionId, {
encounter: { status: "in-progress" },
});
// Delete an interaction
await client.interactions.delete(interactionId);
| Method | Parameters | Returns |
|---|---|---|
list(request?) | Filter and pagination options | Paginated list of interactions |
create(request) | Interaction definition | Created interaction |
get(id) | Interaction UUID | Single interaction |
update(id, request?) | Interaction UUID + update fields | Updated interaction |
delete(id) | Interaction UUID | void |
Recordings
Upload and manage audio recordings within an interaction.JavaScript
import { createReadStream } from "fs";
// Upload a recording
const { recordingId } = await client.recordings.upload(
createReadStream("audio.mp3"),
interactionId,
);
// List recordings for an interaction
const recordings = await client.recordings.list(interactionId);
// Download a recording (returns binary)
const binary = await client.recordings.get(interactionId, recordingId);
const stream = binary.stream();
// Delete a recording
await client.recordings.delete(interactionId, recordingId);
| Method | Parameters | Returns |
|---|---|---|
upload(file, interactionId) | Uploadable file + interaction UUID | Created recording |
list(interactionId) | Interaction UUID | List of recordings |
get(interactionId, recordingId) | Interaction UUID + recording UUID | Binary audio data |
delete(interactionId, recordingId) | Interaction UUID + recording UUID | void |
See File uploads for all supported file input types.
Languages
List available languages and which endpoints support each language.| Method | Parameters | Returns |
|---|---|---|
list(request?) | Optional endpoint filter | Languages with enabled endpoint details |
Transcripts
Create transcriptions from uploaded recordings and retrieve results.JavaScript
// Create a transcript from a recording
const { id: transcriptId } = await client.transcripts.create(interactionId, {
recordingId,
primaryLanguage: "en",
});
// Check transcription status
const status = await client.transcripts.getStatus(interactionId, transcriptId);
// List transcripts for an interaction
const transcripts = await client.transcripts.list(interactionId);
// Get a specific transcript
const result = await client.transcripts.get(interactionId, transcriptId);
// Delete a transcript
await client.transcripts.delete(interactionId, transcriptId);
| Method | Parameters | Returns |
|---|---|---|
create(interactionId, request) | Interaction UUID + transcript definition | Created transcript |
getStatus(interactionId, transcriptId) | Interaction UUID + transcript UUID | Transcription status |
list(interactionId, request?) | Interaction UUID + optional filters | List of transcripts |
get(interactionId, transcriptId) | Interaction UUID + transcript UUID | Single transcript |
delete(interactionId, transcriptId) | Interaction UUID + transcript UUID | void |
Guided Documents
Generate structured clinical documents using guided synthesis. Accepts a template reference, an ad-hoc assembly of sections, or a fully inline dynamic template.| Method | Parameters | Returns |
|---|---|---|
generate(request) | GuidedDocumentsGenerateRequest — one of templateRef, assemblyTemplate, or dynamicTemplate | Generated document (optional sections: sectionId, heading, labels) |
list(request?) | Optional GuidedDocumentsListRequest (templateId, interactionId, label) | Persisted guided documents |
get(documentId) | Document UUID | Persisted guided document |
update(documentId, request?) | Document UUID + GuidedDocumentsUpdateRequest | Updated document |
delete(documentId) | Document UUID | void |
See the Guided Synthesis guide for the four template-supply paths and context options.
Guided Templates
Create, version, and publish document templates that define section composition and generation instructions.| Method | Parameters | Returns |
|---|---|---|
list(request?) | Optional filters (lang, region, specialty, label, published, source) | List of templates |
create(request) | Template definition (name, sections, lang, etc.) | Created template |
get(templateId) | Template UUID | Single template |
update(templateId, request?) | Template UUID + update fields | Updated template |
delete(templateId) | Template UUID | void |
Template Versions
| Method | Parameters | Returns |
|---|---|---|
templates.versions.list(templateId) | Template UUID | List of versions |
templates.versions.create(templateId, request) | Template UUID + version definition | Created version |
templates.versions.get(templateId, versionId) | Template UUID + version UUID | Single version |
templates.versions.delete(templateId, versionId) | Template UUID + version UUID | void |
templates.versions.publish(templateId, versionId) | Template UUID + version UUID | Status response |
Guided Sections
Create, version, and publish document sections that define individual clinical note components with structured output schemas.| Method | Parameters | Returns |
|---|---|---|
list(request?) | Optional filters (lang, region, specialty, label, published, source) | List of sections |
create(request) | Section definition (name, generation config, outputSchema) | Created section |
get(sectionId) | Section UUID | Single section |
update(sectionId, request?) | Section UUID + update fields | Updated section |
delete(sectionId) | Section UUID | void |
Section Versions
| Method | Parameters | Returns |
|---|---|---|
sections.versions.list(sectionId) | Section UUID | List of versions |
sections.versions.create(sectionId, request) | Section UUID + version definition | Created version |
sections.versions.get(sectionId, versionId) | Section UUID + version UUID | Single version |
sections.versions.delete(sectionId, versionId) | Section UUID + version UUID | void |
sections.versions.publish(sectionId, versionId) | Section UUID + version UUID | Status response |
// --- Templates ---
// List templates (with optional filters)
const templates = await client.documents.templates.list({
lang: ["en"],
published: true,
});
// Create a template from scratch
const template = await client.documents.templates.create({
name: "My Template",
description: "Custom SOAP note",
lang: "en",
sections: [{ sectionId: "<section-uuid>", order: 0 }],
});
// Get / update / delete a template
const tmpl = await client.documents.templates.get(templateId);
await client.documents.templates.update(templateId, { name: "Renamed" });
await client.documents.templates.delete(templateId);
// --- Template Versions ---
const versions = await client.documents.templates.versions.list(templateId);
const version = await client.documents.templates.versions.create(templateId, {
sections: [{ sectionId: "<section-uuid>", order: 0 }],
});
await client.documents.templates.versions.publish(templateId, versionId);
await client.documents.templates.versions.delete(templateId, versionId);
// --- Sections ---
const sections = await client.documents.sections.list({ lang: ["en"] });
const section = await client.documents.sections.create({
name: "HPI",
generation: {
heading: "History of Present Illness",
instructions: { contentPrompt: "Summarize the patient history" },
outputSchema: { type: "string" },
},
});
await client.documents.sections.update(sectionId, { name: "Renamed" });
await client.documents.sections.delete(sectionId);
// --- Section Versions ---
const sectionVersions = await client.documents.sections.versions.list(sectionId);
await client.documents.sections.versions.publish(sectionId, versionId);
// --- Generate ---
const result = await client.documents.generate({
outputLanguage: "en-US",
interactionId: "<interaction-uuid>",
templateRef: { templateId: "<template-uuid>" },
});
// List / get / update / delete persisted documents
const documents = await client.documents.list();
const doc = await client.documents.get(documentId);
await client.documents.update(documentId, { name: "Renamed" });
await client.documents.delete(documentId);
Documents (Classic)
These interaction-scoped methods are deprecated. Use Guided Documents with
client.documents.generate() instead. Call sites are client.documents.classic.*.// Generate a document
const { id: documentId } = await client.documents.classic.create(interactionId, {
context: [{
type: "string",
data: "Patient presents with chest pain...",
}],
templateKey: "corti-soap",
outputLanguage: "en",
});
// List documents for an interaction
const documents = await client.documents.classic.list(interactionId);
// Get a specific document
const doc = await client.documents.classic.get(interactionId, documentId);
// Update a document
await client.documents.classic.update(interactionId, documentId, {
name: "Updated note",
});
// Delete a document
await client.documents.classic.delete(interactionId, documentId);
| Method | Parameters | Returns |
|---|---|---|
classic.create(interactionId, request) | Interaction UUID + document generation options | Generated document |
classic.list(interactionId) | Interaction UUID | List of documents |
classic.get(interactionId, documentId) | Interaction UUID + document UUID | Single document |
classic.update(interactionId, documentId, request?) | Interaction UUID + document UUID + update fields | Updated document |
classic.delete(interactionId, documentId) | Interaction UUID + document UUID | void |
Facts
Extract structured clinical facts from text or manage facts on an interaction.// Extract facts from text (standalone, no interaction needed)
const extracted = await client.facts.extract({
context: [{ type: "text", text: "Patient has a temperature of 38.5°C and reports headache." }],
outputLanguage: "en",
});
// List facts for an interaction
const facts = await client.facts.list(interactionId);
// Create facts on an interaction
const { id: factId } = await client.facts.create(interactionId, {
facts: [{ text: "Temperature 38.5°C", group: "vitals" }],
});
// Batch update facts
await client.facts.batchUpdate(interactionId, {
facts: [{ factId, text: "Temperature 39.0°C" }],
});
// Update a single fact
await client.facts.update(interactionId, factId, { text: "Temperature 39.0°C" });
// List available fact groups
const groups = await client.facts.factGroupsList();
| Method | Parameters | Returns |
|---|---|---|
extract(request) | Extraction options (context, output language) | Extracted facts |
list(interactionId) | Interaction UUID | List of facts |
create(interactionId, request) | Interaction UUID + fact definitions | Created facts |
batchUpdate(interactionId, request) | Interaction UUID + fact updates | Updated facts |
update(interactionId, factId, request?) | Interaction UUID + fact ID + update fields | Updated fact |
factGroupsList() | None | Available fact group definitions |
Templates
List and inspect document generation templates available to your tenant.JavaScript
// List all templates
const templates = await client.templates.list();
// Get a specific template by key
const template = await client.templates.get("corti-soap");
// List template sections
const sections = await client.templates.sectionList();
| Method | Parameters | Returns |
|---|---|---|
list(request?) | Optional filters | List of templates |
get(key) | Template key string | Single template |
sectionList(request?) | Optional filters | List of template sections |
Codes
Predict medical codes from clinical data.JavaScript
const response = await client.codes.predict({
system: ["icd10cm-inpatient"],
context: [
{
type: "text",
text: "Progress Note — Day 3: Patient continues on IV vancomycin for MRSA bacteremia. Blood cultures from yesterday still pending. Acute kidney injury improving — creatinine down to 1.8 from 2.4. Patient also has history of CHF, currently euvolemic on home dose of furosemide. Diabetes managed with insulin sliding scale, glucose well controlled.",
},
],
});
| Method | Parameters | Returns |
|---|---|---|
predict(request) | Prediction options (text, code system) | Code predictions |
Agents
Create and interact with AI agents.client.agents is Agents API v1 (deprecated). Prefer client.agentic.
| Method | Parameters | Returns |
|---|---|---|
list(request?) | Optional filters | List of agents |
create(request) | Agent definition | Created agent |
get(id) | Agent ID | Agent details |
getCard(id) | Agent ID | Agent card (A2A format) |
getCardUrl(id) | Agent ID | Agent-card URL (helper) |
messageSend(id, request) | Agent ID + message payload | Agent response |
getTask(id, taskId, request?) | Agent ID + task ID | Task details |
getContext(id, contextId, request?) | Agent ID + context ID | Context details |
getRegistryExperts(request?) | Optional filters | Registry experts |
update(id, request?) | Agent ID + update fields | Updated agent |
delete(id) | Agent ID | void |
Agents v2
Agents API v2. Nested underclient.agentic (agents, contexts, registry).
JavaScript
// Replace these with your values
const TASK_ID = "<your-task-id>";
const CONTEXT_ID = "<your-context-id>";
// List agents
const agents = await client.agentic.agents.list();
// Create an agent
const agent = await client.agentic.agents.create({
name: "My Agent",
description: "A helpful assistant",
});
// Get agent details
const details = await client.agentic.agents.get(agent.id);
// Get agent card (A2A)
const card = await client.agentic.agents.card(agent.id);
const cardUrl = await client.agentic.agents.getCardUrl(agent.id);
// Send a message to an agent
const response = await client.agentic.agents.sendMessage(agent.id, {
message: {
role: "ROLE_USER",
parts: [{ text: "Hello" }],
messageId: crypto.randomUUID(),
},
});
// Get a task
const task = await client.agentic.agents.tasks.get(agent.id, TASK_ID);
// Get context (top-level resource, not agent-scoped)
const context = await client.agentic.contexts.get(CONTEXT_ID);
// List registry connectors
const connectors = await client.agentic.registry.connectors.list();
// Patch an agent (v2 uses PATCH with merge-patch semantics)
await client.agentic.agents.update(agent.id, { description: "Updated" });
// Delete an agent
await client.agentic.agents.delete(agent.id);
| Method | Parameters | Returns |
|---|---|---|
agents.list(request?) | Optional filters | Paginated list of agents |
agents.create(request) | Agent definition | Created agent |
agents.get(id) | Agent ID | Agent details |
agents.update(id, request?) | Agent ID + patch | Updated agent |
agents.delete(id) | Agent ID | void |
agents.card(id) | Agent ID | Agent card |
agents.getCardUrl(id) | Agent ID | Agent-card URL (helper) |
agents.jsonRpc(id, request) | Agent ID + JSON-RPC body | JSON-RPC response |
agents.sendMessage(id, request) | Agent ID + message payload | Agent response |
agents.streamMessage(id, request) | Agent ID + message payload | Stream of events |
agents.usage(id, request?) | Agent ID + optional time range | Usage report |
agents.tasks.list(id, request?) | Agent ID + optional filters | Paginated tasks |
agents.tasks.get(id, taskId, request?) | Agent ID + task ID | Task details |
agents.tasks.cancel(id, taskId) | Agent ID + task ID | Cancelled task |
agents.tasks.subscribe(id, taskId) | Agent ID + task ID | Stream of events |
agents.connectors.list(id) | Agent ID | Connector list |
agents.connectors.create(id, request) | Agent ID + connector definition | Created connector |
agents.connectors.get(id, connectorId) | Agent ID + connector ID | Connector details |
agents.connectors.update(id, connectorId, request?) | Agent ID + connector ID + patch | Updated connector |
agents.connectors.delete(id, connectorId) | Agent ID + connector ID | void |
contexts.list(request?) | Optional filters | Paginated contexts |
contexts.get(contextId, request?) | Context ID | Context details |
contexts.delete(contextId) | Context ID | void |
contexts.trace(contextId, request?) | Context ID | Paginated traces |
contexts.tasks.list(contextId, request?) | Context ID | Paginated tasks |
contexts.tasks.get(contextId, taskId) | Context ID + task ID | Task details |
contexts.tasks.artifacts.get(contextId, taskId, artifactId) | Context ID + task ID + artifact ID | Artifact |
contexts.tasks.feedback.list(contextId, taskId) | Context ID + task ID | Feedback list |
contexts.tasks.feedback.create(contextId, taskId, request) | Context ID + task ID + feedback | Created feedback |
contexts.tasks.feedback.delete(contextId, taskId, feedbackId) | Context ID + task ID + feedback ID | void |
registry.connectors.list(request?) | Optional filters | Paginated registry connectors |
registry.connectors.get(connectorId) | Connector ID | Registry connector |
Stream
Real-time WebSocket connection for combined transcription, fact extraction, and more — tied to an interaction.const socket = await client.stream.connect({
id: interactionId,
configuration: {
transcription: {
primaryLanguage: "en",
participants: [{ channel: 0, role: "doctor" }],
},
mode: { type: "facts", outputLocale: "en" },
},
});
socket.on("message", (msg) => {
console.log(msg.type, msg.data);
});
socket.sendAudio(audioBuffer);
connect parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Interaction UUID to attach the stream to |
configuration | Corti.StreamConfig | No | Stream configuration (transcription language, participants, mode). When provided, the SDK automatically sends the config message once the socket opens. If omitted, you must call sendConfiguration() yourself |
awaitConfiguration | boolean | No | When true (default), connect() waits for CONFIG_ACCEPTED before resolving. When false, returns the socket immediately and dispatches config errors as events |
proxy | ProxyOptions | No | Route through a proxy instead of connecting directly. Connects to the provided URL exactly as-is (no endpoint path is appended) |
queryParams | Record<string, unknown> | No | Extra query string parameters on the WebSocket URL. Merged with analytics keys. When proxy is set, use proxy.queryParameters instead |
debug | boolean | No | Enable debug logging |
reconnectAttempts | number | No | Number of reconnection attempts on disconnect |
tenantName and token automatically. If configuration is provided and awaitConfiguration is true, the promise rejects when the stream configuration is denied (CONFIG_DENIED, CONFIG_MISSING, CONFIG_NOT_PROVIDED).
Socket methods
| Method | Description |
|---|---|
on(event, handler) | Subscribe to events: "open", "message", "close", "error" |
off(event, handler?) | Remove an event handler |
sendAudio(data) | Send binary audio data (ArrayBuffer, Blob, or ArrayBufferView) |
sendFlush(message) | Request the server to flush buffered audio and return results |
sendEnd(message) | Signal end of audio stream |
sendConfiguration(message) | Send a configuration message (used internally by connect) |
send(data) | Send raw data directly on the underlying WebSocket |
close() | Close the connection and unregister event handlers. You should call sendEnd() first and wait for the ended message before closing — see Flush the Audio Buffer |
waitForOpen() | Returns a promise that resolves when the socket is open |
readyState | Current connection state (property, not method) |
Transcribe
Real-time WebSocket speech-to-text without an interaction context.JavaScript
const socket = await client.transcribe.connect({
configuration: {
primaryLanguage: "en",
automaticPunctuation: true,
},
});
socket.on("message", (message) => {
if (message.type === "transcript") {
console.log("Transcript:", message.data.text);
}
});
// Send audio data (e.g. from a microphone stream)
socket.sendAudio(audioBuffer);
connect parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
configuration | Corti.TranscribeConfig | No | Transcribe configuration (language, punctuation, commands). When provided, the SDK automatically sends the config message once the socket opens. If omitted, you must call sendConfiguration() yourself |
awaitConfiguration | boolean | No | When true (default), connect() waits for CONFIG_ACCEPTED before resolving. When false, returns the socket immediately and dispatches config errors as events |
proxy | ProxyOptions | No | Route through a proxy instead of connecting directly. Connects to the provided URL exactly as-is (no endpoint path is appended) |
queryParams | Record<string, unknown> | No | Extra query string parameters on the WebSocket URL. Merged with analytics keys. When proxy is set, use proxy.queryParameters instead |
debug | boolean | No | Enable debug logging |
reconnectAttempts | number | No | Number of reconnection attempts on disconnect |
sendAudio, sendFlush, sendEnd, close, etc.). The key differences are:
- No interaction ID — Transcribe operates standalone
- Different message types — Transcribe delivers
transcript,command,flushed,ended,usage,delta_usage, anderrormessages, while Stream deliverstranscript,facts,flushed,ended,usage,delta_usage, anderror
Auth
OAuth token management. In most cases you won’t call these directly — the SDK handles tokens automatically based on theauth option you pass to the constructor. These methods are useful for advanced scenarios like generating authorization URLs for browser-based flows.
| Method | Description |
|---|---|
getToken(request) | Get a token via client credentials |
getRopcFlowToken(request) | Get a token via ROPC flow |
getCodeFlowToken(request) | Exchange an authorization code for a token |
getPkceFlowToken(request) | Exchange a PKCE authorization code for a token |
refreshToken(request) | Refresh an expired token |
authorizeURL(options) | Generate an authorization code flow URL and redirect to it |
authorizePkceUrl(options) | Generate a PKCE flow redirect URL |
For detailed usage and end-to-end examples, see the Authentication Guide. For standalone use without
CortiClient, see CortiAuth below.CortiAuth
A standalone authentication client for when you need OAuth token management without the fullCortiClient. Useful for proxy servers, custom backends, or applications that handle tokens separately from API calls.
JavaScript
import { CortiAuth } from "@corti/sdk";
const auth = new CortiAuth({
environment: "<eu-or-us>",
tenantName: "<your-tenant-name>",
});
Constructor options
| Option | Type | Required | Description |
|---|---|---|---|
environment | CortiEnvironment | CortiEnvironmentUrls | string | Yes | API region or custom URLs |
tenantName | string | Yes | Your Corti tenant name |
headers | Record<string, string> | No | Additional headers |
timeoutInSeconds | number | No | Request timeout |
maxRetries | number | No | Retry count |
Methods
All token methods accept an optionalscopes array. openid and profile are added automatically — pass additional scopes like "streams" or "transcribe" to get a scoped token.
| Method | Description | Returns |
|---|---|---|
getToken(request) | Get a token via client credentials | AuthTokenResponse |
getRopcFlowToken(request) | Get a token via ROPC flow | AuthTokenResponse |
getCodeFlowToken(request) | Exchange an authorization code for a token | AuthTokenResponse |
getPkceFlowToken(request) | Exchange a PKCE authorization code for a token | AuthTokenResponse |
refreshToken(request) | Refresh an expired token | AuthTokenResponse |
authorizeURL(options) | Generate an authorization code flow URL and redirect to it | string |
authorizePkceUrl(options) | Generate a PKCE flow redirect URL | string |
CortiAuth.getCodeVerifier() | Get the PKCE code verifier from the last authorizePkceUrl call (static) | string | null |
For end-to-end examples and detailed usage of each method, see the Authentication Guide.
CortiWebSocketProxyClient
A lightweight client for WebSocket-only proxy scenarios. UnlikeCortiClient, it requires no environment, tenant, or authentication configuration — all routing is handled by the proxy option you pass at connect time.
JavaScript
import { CortiWebSocketProxyClient } from "@corti/sdk";
Static properties
| Property | Type | Description |
|---|---|---|
stream | CustomProxyStream | Stream proxy client (transcription + facts, tied to an interaction) |
transcribe | CustomProxyTranscribe | Transcribe proxy client (standalone speech-to-text) |
stream.connect
const socket = await CortiWebSocketProxyClient.stream.connect({
proxy: {
url: "wss://your-proxy.com/corti/stream",
protocols: ["custom-protocol"],
queryParameters: { interactionId: "id" },
},
configuration: {
transcription: {
primaryLanguage: "en",
participants: [{ channel: 0, role: "doctor" }],
},
mode: { type: "facts", outputLocale: "en" },
},
awaitConfiguration: true, // default: true
debug: false,
reconnectAttempts: 3,
});
socket.on("message", (msg) => console.log(msg.type, msg.data));
socket.sendAudio(audioBuffer);
| Parameter | Type | Required | Description |
|---|---|---|---|
proxy | ProxyOptions | Yes | Proxy URL, subprotocols, and query parameters. Connects to the provided URL exactly as-is (no endpoint path is appended) |
configuration | Corti.StreamConfig | No | Stream configuration (language, punctuation, etc.) |
awaitConfiguration | boolean | No | Wait for CONFIG_ACCEPTED before resolving (default true) |
debug | boolean | No | Enable debug logging |
reconnectAttempts | number | No | Number of reconnection attempts |
Promise<CustomStreamSocket> — same socket API as client.stream.connect.
transcribe.connect
const socket = await CortiWebSocketProxyClient.transcribe.connect({
proxy: {
url: "wss://your-proxy.com/corti/transcribe",
},
configuration: {
primaryLanguage: "en",
automaticPunctuation: true,
},
});
socket.on("message", (msg) => {
if (msg.type === "transcript") {
console.log(msg.data.text);
}
});
socket.sendAudio(audioBuffer);
| Parameter | Type | Required | Description |
|---|---|---|---|
proxy | ProxyOptions | Yes | Proxy URL, subprotocols, and query parameters. Connects to the provided URL exactly as-is (no endpoint path is appended) |
configuration | Corti.TranscribeConfig | No | Transcribe configuration (language, punctuation, etc.) |
awaitConfiguration | boolean | No | Wait for CONFIG_ACCEPTED before resolving (default true) |
debug | boolean | No | Enable debug logging |
reconnectAttempts | number | No | Number of reconnection attempts |
Promise<CustomTranscribeSocket> — same socket API as client.transcribe.connect.
ProxyOptions
The ProxyOptions type is also exported from @corti/sdk for use when typing proxy arguments in your own code.
JavaScript
import type { ProxyOptions } from "@corti/sdk";
| Property | Type | Required | Description |
|---|---|---|---|
url | string | Yes | WebSocket URL of your proxy server |
protocols | string[] | Record<string, string> | No | WebSocket subprotocols. Arrays are passed as-is; objects are encoded as [name, encodeURIComponent(value), ...] pairs |
queryParameters | Record<string, string> | No | Query parameters appended to the WebSocket URL |
For a full walkthrough of proxy patterns (including
baseUrl, custom environments, encodeHeadersAsWsProtocols, and scoped tokens), see the Proxy Guide.Utilities
The@corti/sdk/utils sub-package exports helper functions for token inspection, environment resolution, PKCE, and dictation transcript assembly. These are useful in proxy servers, middleware, custom authentication flows, and dictation UIs.
JavaScript
import {
decodeToken,
getEnvironment,
generateCodeVerifier,
generateCodeChallenge,
applyDictationTranscript,
} from "@corti/sdk/utils";
| Export | Description |
|---|---|
decodeToken(token) | Decode a Corti JWT to extract environment, tenantName, accessToken, and expiresAt. Returns null if the token is invalid or the issuer doesn’t match |
getEnvironment(env) | Normalize an environment string (e.g. "eu") or CortiEnvironment object into the internal URL format the SDK uses |
generateCodeVerifier() | Generate a PKCE code verifier (32 random bytes, base64url-encoded) |
generateCodeChallenge(verifier) | Compute the PKCE code challenge from a verifier (SHA-256, base64url-encoded). Returns a Promise |
applyDictationTranscript(previous, message) | Apply a /transcribe transcript packet to a prior snapshot; returns updated committedText and interimText |
DecodedToken | TypeScript type for the return value of decodeToken |