TypeScript SDK for Syynk API - transcribe audio and export synchronized lyrics/subtitles
npm install @royalti/syynkTypeScript SDK for the Syynk API - transcribe audio and export synchronized lyrics/subtitles.
``bash`
npm install @royalti/syynkor
yarn add @royalti/syynkor
pnpm add @royalti/syynk
`typescript
import { SyynkClient } from '@royalti/syynk';
const client = new SyynkClient({
apiKey: process.env.SYYNK_API_KEY,
});
// Transcribe audio from URL
const result = await client.transcribe({
audioUrl: 'https://example.com/song.mp3',
language: 'en',
});
// Export to LRC format
const lrc = await client.export({
format: 'lrc',
segments: result.segments,
projectName: 'My Song',
});
console.log(lrc.content);
`
- Transcribe audio from URL or file upload
- Export to multiple formats: LRC, SRT, VTT, TTML, JSON, TXT
- Full TypeScript support
- Automatic retry with exponential backoff
- Rate limit handling
- Works in Node.js (18+) and browsers
Create a new client instance:
`typescript`
const client = new SyynkClient({
apiKey: 'your-api-key',
baseUrl: 'https://syynk.to', // optional
timeout: 30000, // optional, in milliseconds
maxRetries: 3, // optional
});
#### transcribe(options)
Transcribe audio from a URL.
`typescript
const result = await client.transcribe({
audioUrl: 'https://example.com/song.mp3',
language: 'en', // optional, auto-detected if not specified
projectName: 'My Song', // optional
});
// Result contains:
// - projectId: string
// - editorUrl: string (URL to open in Syynk editor)
// - language: string
// - duration: number (seconds)
// - lyricsText: string (plain text lyrics)
// - segments: Segment[]
// - words: Word[]
`
#### transcribeFile(file, options?)
Transcribe audio from a file upload.
`typescript
// Node.js
import fs from 'fs';
const buffer = fs.readFileSync('song.mp3');
const result = await client.transcribeFile(buffer, {
filename: 'song.mp3',
language: 'en',
});
// Browser
const file = document.querySelector('input[type="file"]').files[0];
const result = await client.transcribeFile(file);
`
#### export(options)
Export segments to a specific format.
`typescript
const result = await client.export({
format: 'lrc', // 'lrc' | 'srt' | 'vtt' | 'ttml' | 'json' | 'txt'
segments: transcription.segments,
words: transcription.words, // optional, for word-level timing
projectName: 'My Song', // optional
});
// Result contains:
// - content: string
// - filename: string
// - mimeType: string
// - extension: string
`
#### getFormats()
Get information about available export formats.
`typescript
const formats = await client.getFormats();
// Returns:
// [
// { id: 'lrc', name: 'LRC', supportsWordTiming: false, ... },
// { id: 'ttml', name: 'TTML', supportsWordTiming: true, ... },
// ...
// ]
`
#### listProjects(options?)
List your projects with optional filtering.
`typescript
const result = await client.listProjects({
status: 'ready',
type: 'lyricsync',
limit: 20,
offset: 0,
});
// Result contains:
// - projects: ProjectSummary[]
// - total: number
// - limit: number
// - offset: number
`
#### getProject(id, options?)
Get a single project with segments and optionally words.
`typescript
const result = await client.getProject('project-id', {
includeWords: true, // default: true
});
// Result contains:
// - project: Project (id, name, type, status, editorUrl, audioUrl, etc.)
// - segments: Segment[]
// - words?: Word[] (if includeWords is true)
`
#### getLyrics(id)
Get plain text lyrics for a project.
`typescript`
const result = await client.getLyrics('project-id');
console.log(result.lyrics);
// "First line of lyrics\nSecond line\n..."
#### deleteProject(id)
Delete a project and all its segments and words.
`typescript`
await client.deleteProject('project-id');
console.log('Project deleted');
#### getRateLimitInfo()
Get the current rate limit status.
`typescript
const rateLimit = client.getRateLimitInfo();
if (rateLimit) {
console.log(${rateLimit.remaining}/${rateLimit.limit} requests remaining);Resets at ${new Date(rateLimit.reset * 1000)}
console.log();`
}
The SDK provides typed errors for different failure scenarios:
`typescript
import {
SyynkClient,
AuthenticationError,
RateLimitError,
ValidationError,
NotFoundError,
ServerError,
NetworkError,
TimeoutError,
} from '@royalti/syynk';
try {
const result = await client.transcribe({ audioUrl: 'invalid' });
} catch (error) {
if (error instanceof AuthenticationError) {
// Invalid or missing API key (401)
console.log('Check your API key');
} else if (error instanceof RateLimitError) {
// Rate limit exceeded (429)
console.log(Retry after ${error.retryAfter} seconds);Reset time: ${error.getResetDate()}
console.log();Request ID: ${error.requestId}
} else if (error instanceof ValidationError) {
// Invalid request data (400)
console.log(error.fieldErrors);
} else if (error instanceof NotFoundError) {
// Resource not found (404)
console.log('Project not found');
} else if (error instanceof ServerError) {
// Server error (500+)
console.log();Timed out after ${error.timeoutMs}ms
} else if (error instanceof NetworkError) {
// Connection failed
console.log('Check your internet connection');
} else if (error instanceof TimeoutError) {
// Request timed out
console.log();`
}
}
`typescript
import { isSyynkError, isRateLimitError, isRetryableError } from '@royalti/syynk';
if (isSyynkError(error)) {
console.log(error.code, error.status);
}
if (isRateLimitError(error)) {
console.log(error.retryAfter);
}
if (isRetryableError(error)) {
// Error is rate limit, network, timeout, or server error
}
`
All types are exported for TypeScript users:
`typescript`
import type {
Segment,
Word,
Project,
ProjectSummary,
ProjectResult,
LyricsResult,
ExportFormat,
TranscribeResult,
ExportResult,
} from '@royalti/syynk';
| Format | Extension | Word Timing | Use Case |
|--------|-----------|-------------|----------|
| LRC | .lrc | No | Karaoke players |.srt
| SRT | | No | Video subtitles (VLC, YouTube) |.vtt
| VTT | | No | HTML5
MIT