import type {
SpekoClientOptions,
KeySource,
Vertical,
OptimizeFor,
RoutingIntent,
PipelineConstraints,
TranscribeOptions,
TranscribeResult,
SynthesizeOptions,
SynthesizeResult,
ChatMessage,
CompleteParams,
CompleteResult,
UsageSummary,
UsageByProvider,
UsageQueryParams,
OrganizationBalance,
CreditLedgerEntry,
CreditLedgerKind,
CreditLedgerPage,
CreditLedgerQueryParams,
RealtimeProvider,
RealtimeToolSpec,
RealtimeConnectParams,
RealtimeFrame,
RealtimeEventHandler,
RealtimeSessionHandle,
} from '@spekoai/sdk';
Routing primitives
Vertical
type Vertical = 'general' | 'healthcare' | 'finance' | 'legal';
OptimizeFor
type OptimizeFor = 'balanced' | 'accuracy' | 'latency' | 'cost';
balanced is the default.
RoutingIntent
interface RoutingIntent {
language: string; // BCP-47, e.g. "en" or "es-MX"
vertical: Vertical;
optimizeFor?: OptimizeFor;
}
TranscribeOptions and SynthesizeOptions extend it directly.
PipelineConstraints
interface PipelineConstraints {
allowedProviders?: {
stt?: string[];
llm?: string[];
tts?: string[];
};
}
RoutingIntent. When set, the router still ranks by benchmark score but considers only candidates in the allow-list for that modality.
Transcribe
interface TranscribeOptions extends RoutingIntent {
contentType?: string; // default "audio/wav"
constraints?: PipelineConstraints;
}
interface TranscribeResult {
text: string;
provider: string;
model: string;
confidence: number | null;
failoverCount: number;
scoresRunId: string | null;
}
Synthesize
interface SynthesizeOptions extends RoutingIntent {
voice?: string;
speed?: number;
constraints?: PipelineConstraints;
}
interface SynthesizeResult {
audio: Uint8Array;
contentType: string; // e.g. "audio/pcm;rate=24000" or "audio/mpeg"
provider: string;
model: string;
failoverCount: number;
scoresRunId: string | null;
}
Complete
interface ChatMessage {
role: 'system' | 'user' | 'assistant';
content: string;
}
interface CompleteParams {
messages: ChatMessage[];
intent: RoutingIntent;
systemPrompt?: string;
temperature?: number;
maxTokens?: number;
constraints?: PipelineConstraints;
}
interface CompleteResult {
text: string;
provider: string;
model: string;
usage: {
promptTokens: number;
completionTokens: number;
};
failoverCount: number;
scoresRunId: string | null;
}
Usage
type KeySource = 'BYOK' | 'MANAGED';
interface UsageQueryParams {
from?: string; // ISO-8601
to?: string; // ISO-8601
}
interface UsageSummary {
totalSessions: number;
totalMinutes: number;
totalCost: number;
breakdown: UsageByProvider[];
balanceMicroUsd: string; // µ$ as string so values > 2^53 survive JSON
balanceUsd: number;
}
interface UsageByProvider {
provider: string;
type: 'stt' | 'llm' | 'tts';
metric: string;
keySource: KeySource;
quantity: number;
cost: number;
}
Credits
interface OrganizationBalance {
balanceMicroUsd: string;
balanceUsd: number;
updatedAt: string;
}
type CreditLedgerKind =
| 'grant'
| 'debit'
| 'topup'
| 'refund'
| 'adjustment';
interface CreditLedgerEntry {
id: string;
kind: CreditLedgerKind;
/** Signed. Positive for grants/topups/refunds, negative for debits. */
amountMicroUsd: string;
metric: string | null;
provider: string | null;
sessionId: string | null;
createdAt: string;
}
interface CreditLedgerPage {
entries: CreditLedgerEntry[];
nextCursor: string | null;
}
interface CreditLedgerQueryParams {
limit?: number;
cursor?: string;
}
Realtime (S2S)
type RealtimeProvider = 'openai' | 'google' | 'xai';
interface RealtimeToolSpec {
name: string;
description: string;
parameters: Record<string, unknown>;
}
interface RealtimeConnectParams {
provider: RealtimeProvider;
model: string;
voice?: string;
systemPrompt?: string;
temperature?: number;
inputSampleRate?: 16000 | 24000;
outputSampleRate?: 16000 | 24000;
tools?: RealtimeToolSpec[];
metadata?: Record<string, unknown>;
/** Max session duration in seconds. Server-capped at 1800 (30 min). */
ttlSeconds?: number;
}
type RealtimeFrame =
| { type: 'audio'; pcm: Uint8Array; sampleRate: number }
| {
type: 'transcript';
role: 'user' | 'assistant';
text: string;
final: boolean;
}
| {
type: 'tool_call';
callId: string;
name: string;
arguments: string;
}
| {
type: 'usage';
inputAudioTokens: number;
outputAudioTokens: number;
}
| { type: 'error'; code: string; message: string }
| { type: 'close'; code: number; reason: string };
type RealtimeEventHandler = (frame: RealtimeFrame) => void;
interface RealtimeSessionHandle {
readonly sessionId: string;
readonly expiresAt: string;
sendAudio(pcm: Uint8Array): void;
commit(): void;
interrupt(): void;
sendToolResult(callId: string, output: string): void;
on(handler: RealtimeEventHandler): () => void;
close(code?: number, reason?: string): void;
}
Client
interface SpekoClientOptions {
apiKey: string;
baseUrl?: string; // default "https://api.speko.ai"
timeout?: number; // default 30000
}