@wisprs/sdk
v0.1.1
Published
Official TypeScript client for the Wisprs API platform.
Maintainers
Readme
@wisprs/sdk
Official TypeScript/JavaScript SDK for the Wisprs transcription API.
Zero runtime dependencies. Works in Node.js, Bun, Deno, and browser environments.
Get an API key · Full docs · API reference
Install
npm install @wisprs/sdk
# or
yarn add @wisprs/sdk
# or
bun add @wisprs/sdkQuick start
import { WisprsClient } from '@wisprs/sdk';
const client = new WisprsClient({ apiKey: process.env.WISPRS_API_KEY! });
// Submit a YouTube video for transcription
const job = await client.transcriptions.create({
source: { url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ' },
});
// Wait until it's done (polls every 2s, times out after 2min)
const result = await client.jobs.wait(job.id);
console.log(result.transcriptText);Client
const client = new WisprsClient({
apiKey: string; // required — from wisprs.co/developer
baseUrl?: string; // default: 'https://wisprs.co'
fetch?: typeof fetch; // optional — bring your own fetch (e.g. for testing)
});Transcriptions
transcriptions.create(input)
Submit a URL for transcription. Returns immediately with a job ID — transcription happens asynchronously.
const job = await client.transcriptions.create({
source: { url: 'https://...' }, // YouTube, podcast, TikTok, direct audio/video URL
language?: string, // BCP-47 code, e.g. 'en', 'fr', 'sw'. Auto-detected if omitted
fileName?: string, // hint for display purposes
webhookUrl?: string, // POST when job completes
webhookSecret?: string, // used to sign the webhook payload
options?: {
sttQuality?: 'fast' | 'balanced' | 'accurate', // default: 'balanced'
},
});
// returns: { id: number, status: string, createdAt?: string }transcriptions.get(id)
Fetch a completed transcription by its numeric ID.
const transcription = await client.transcriptions.get(42);transcriptions.export(id, options)
Export a transcript in a specific format. Returns a string for text formats and a Blob for docx.
const srt = await client.transcriptions.export(42, { format: 'srt' });
// format: 'txt' | 'srt' | 'vtt' | 'json' | 'md' | 'docx'transcriptions.summary(id)
Generate a structured AI summary.
const summary = await client.transcriptions.summary(42);
// returns: {
// keyPoints: string[]
// timeline: { time: string; event: string }[]
// topics: string[]
// sentiment: 'positive' | 'neutral' | 'negative'
// wordCount: number
// duration: string
// }transcriptions.chapters(id)
Generate timestamped chapters.
const chapters = await client.transcriptions.chapters(42);
// returns: { id: string; title: string; startTime: number; endTime: number; summary: string }[]transcriptions.quotes(id)
Extract key quotes from the transcript.
const { content } = await client.transcriptions.quotes(42);transcriptions.thread(id)
Turn the transcript into a social media thread.
const { content } = await client.transcriptions.thread(42);transcriptions.blog(id)
Turn the transcript into a blog post.
const { content } = await client.transcriptions.blog(42);transcriptions.showNotes(id)
Generate podcast-style show notes.
const { content } = await client.transcriptions.showNotes(42);transcriptions.repurpose(id, options)
Generic repurpose — use this when you need the mode to be dynamic.
const result = await client.transcriptions.repurpose(42, {
mode: 'thread', // 'summary' | 'chapters' | 'quotes' | 'show-notes' | 'thread' | 'blog'
});transcriptions.translate(id, options)
Translate a transcript into another language.
const translation = await client.transcriptions.translate(42, {
targetLanguage: 'fr', // BCP-47 code
sourceLanguage?: 'en', // optional — auto-detected if omitted
});
// returns: { transcriptionId, targetLanguage, sourceLanguage, translatedText }Jobs
Transcription runs as a background job. Use the jobs namespace to track it.
jobs.get(id)
Fetch the current status of a job.
const job = await client.jobs.get(42);
// returns: {
// id: number
// status: 'queued' | 'processing' | 'completed' | 'failed'
// progress: number // 0–100
// transcriptText: string | null
// language: string | null
// updatedAt: string
// }jobs.wait(id, options?)
Poll until the job reaches completed or failed. The simplest way to handle async transcription.
const result = await client.jobs.wait(42, {
intervalMs?: number, // polling interval, default 2000ms (min 250ms)
timeoutMs?: number, // give up after this long, default 120000ms (2 min)
});Throws WisprsApiError with status 408 if the timeout is reached before completion.
jobs.retry(id)
Retry a failed job.
const job = await client.jobs.retry(42);Library search
Semantic search across all transcripts in your account.
library.search(query, options?)
const { hits } = await client.library.search('product launch metrics', { limit: 5 });
// hits: { id, title, transcriptText, score, ...}[]Webhooks
Register endpoints to receive real-time job completion events.
webhooks.listEndpoints()
const { endpoints } = await client.webhooks.listEndpoints();webhooks.createEndpoint(input)
const { endpoint } = await client.webhooks.createEndpoint({
url: 'https://your-app.com/webhooks/wisprs',
});
// Save endpoint.signingSecret — it is only returned oncewebhooks.updateEndpoint(id, input)
await client.webhooks.updateEndpoint(1, { isActive: false });webhooks.listDeliveries(options?)
const { deliveries } = await client.webhooks.listDeliveries({
endpointId?: number,
status?: 'success' | 'failed',
limit?: number,
});webhooks.retryDelivery(id)
await client.webhooks.retryDelivery(deliveryId);webhooks.sendTest(input)
Send a test event to verify your endpoint is reachable.
await client.webhooks.sendTest({
url: 'https://your-app.com/webhooks/wisprs',
eventType?: string,
signingSecret?: string,
});Usage
usage.get()
Fetch your current month's API usage and recent request log.
const { usageRows, recentRequests } = await client.usage.get();Error handling
All methods throw WisprsApiError on non-2xx responses.
import { WisprsClient, WisprsApiError } from '@wisprs/sdk';
try {
const job = await client.transcriptions.create({ source: { url: '...' } });
} catch (err) {
if (err instanceof WisprsApiError) {
console.error(err.status); // HTTP status code, e.g. 401, 429
console.error(err.message); // error message from the API
}
}Common status codes:
| Status | Meaning |
|--------|---------|
| 401 | Invalid or missing API key |
| 402 | Plan limit reached — upgrade at wisprs.co/pricing |
| 404 | Transcription or job not found |
| 408 | jobs.wait() timed out |
| 429 | Rate limit hit — back off and retry |
End-to-end example
Transcribe a podcast episode and generate show notes + an SRT file.
import { WisprsClient, WisprsApiError } from '@wisprs/sdk';
const client = new WisprsClient({ apiKey: process.env.WISPRS_API_KEY! });
async function processPodcast(url: string) {
// 1. Submit
const job = await client.transcriptions.create({
source: { url },
language: 'en',
options: { sttQuality: 'accurate' },
});
console.log(`Job ${job.id} queued`);
// 2. Wait for completion
const result = await client.jobs.wait(job.id, { timeoutMs: 300_000 });
if (result.status === 'failed') {
throw new Error('Transcription failed');
}
// 3. Export
const [srt, showNotes] = await Promise.all([
client.transcriptions.export(job.id, { format: 'srt' }),
client.transcriptions.showNotes(job.id),
]);
return { transcript: result.transcriptText, srt, showNotes: showNotes.content };
}
processPodcast('https://example.com/episode.mp3').catch(console.error);License
MIT
