vyonica
v0.3.0
Published
JavaScript/TypeScript SDK for the Vyonica voice cloning API
Maintainers
Readme
vyonica
JavaScript/TypeScript SDK for the Vyonica voice cloning API.
Installation
npm install vyonicaRequirements
- Node.js 18+ (uses native
fetchandFormData)
Usage
1. Initialize the client
import { VyonicaClient } from 'vyonica';
const client = new VyonicaClient({
apiKey: 'nvsk_your_api_key_here',
baseUrl: 'http://localhost:8000', // default
});2. One-liner clone (recommended)
The clone() method handles everything: submitting the job, polling for completion, and returning the audio buffer.
import { VyonicaClient } from 'vyonica';
import fs from 'fs';
const client = new VyonicaClient({ apiKey: 'nvsk_...' });
const audioBuffer = await client.clone(
fs.readFileSync('reference.wav'),
{ text: 'Hello world', language: 'en' }
);
fs.writeFileSync('output.wav', audioBuffer);With custom poll options:
const audioBuffer = await client.clone(
fs.readFileSync('reference.wav'),
{
text: 'Hello world',
language: 'en',
temperature: 0.7,
exaggeration: 0.5,
},
{
intervalMs: 3000, // poll every 3 seconds (default: 2000)
timeoutMs: 120_000, // give up after 2 minutes (default: 300_000)
}
);3. Manual job flow
Use this when you need more control — for example, submitting many jobs and downloading results later.
import { VyonicaClient } from 'vyonica';
import fs from 'fs';
const client = new VyonicaClient({ apiKey: 'nvsk_...' });
const refWav = fs.readFileSync('reference.wav');
// Submit job
const job = await client.createCloneJob(refWav, {
text: 'Hello from Vyonica',
language: 'en',
name: 'my-voice',
});
console.log('Job created:', job.jobId);
// Poll manually
let status = await client.getJob(job.jobId);
while (status.status === 'pending' || status.status === 'processing') {
console.log('Status:', status.status);
await new Promise((r) => setTimeout(r, 2000));
status = await client.getJob(job.jobId);
}
// Download result
if (status.status === 'completed') {
const audio = await client.downloadOutput(job.jobId);
fs.writeFileSync('output.wav', audio);
console.log('Done!');
}4. Clone options
There are two ways to control synthesis:
AI Mode — set style + speed together and let the backend pick optimized parameters for you.
Scientific Mode — set the lower-level numeric knobs (temperature, cfgWeight, etc.) directly.
If you set neither, the backend uses its built-in defaults ("Default Mode").
| Option | Type | Default | Description |
|---|---|---|---|
| text | string | required | Text to synthesize |
| language | string | "en" | Source language code |
| synthesisLanguage | string | — | Output language (if different) |
| name | string | — | Label for this voice |
| referenceVoiceName | string | — | Name of the reference voice |
| style | "natural" \| "energetic" \| "serious" | — | AI Mode: speaking style preset. Pair with speed. |
| speed | "slow" \| "normal" \| "fast" \| "very_fast" | — | AI Mode: speaking speed preset. Pair with style. |
| cfgWeight | number | — | CFG guidance weight (Scientific Mode) |
| exaggeration | number | — | Expressiveness exaggeration (Scientific Mode) |
| temperature | number | — | Sampling temperature (Scientific Mode) |
| topP | number | — | Top-p sampling (Scientific Mode) |
| minP | number | — | Min-p sampling (Scientific Mode) |
| repetitionPenalty | number | — | Repetition penalty (Scientific Mode) |
Example: AI Mode
const audio = await client.clone(
fs.readFileSync('reference.wav'),
{
text: 'Hello from Vyonica',
language: 'en',
style: 'energetic',
speed: 'fast',
}
);5. Checking remaining quota
Each API key has a lifetime cap on minutes of generated audio. Once the cap
is reached the server returns 429 and the SDK throws QuotaExceededError.
const usage = await client.getUsage();
console.log(
`${usage.minutesUsed.toFixed(1)} / ${usage.minutesLimit ?? '∞'} min used`
);
if (usage.minutesRemaining !== null && usage.minutesRemaining < 5) {
console.warn('Less than 5 minutes left on this API key.');
}6. Error handling
import {
VyonicaClient,
AuthenticationError,
QuotaExceededError,
JobFailedError,
JobTimeoutError,
VyonicaError,
} from 'vyonica';
const client = new VyonicaClient({ apiKey: 'nvsk_...' });
try {
const audio = await client.clone(refWav, { text: 'Hello' });
fs.writeFileSync('output.wav', audio);
} catch (e) {
if (e instanceof AuthenticationError) {
console.error('Bad API key — check your credentials');
} else if (e instanceof QuotaExceededError) {
console.error('Rate limit hit — slow down or upgrade your plan');
} else if (e instanceof JobFailedError) {
console.error(`Job ${e.jobId} failed: ${e.errorMessage}`);
} else if (e instanceof JobTimeoutError) {
console.error(`Job ${e.jobId} timed out`);
} else if (e instanceof VyonicaError) {
console.error(`API error ${e.statusCode}: ${e.message}`);
} else {
throw e; // re-throw unexpected errors
}
}API Reference
new VyonicaClient(options)
| Option | Type | Default | Description |
|---|---|---|---|
| apiKey | string | required | Your nvsk_ API key |
| baseUrl | string | "http://localhost:8000" | API base URL |
client.clone(refWav, options, pollOptions?): Promise<Buffer>
High-level method: submits job, polls until done, returns audio buffer.
client.createCloneJob(refWav, options): Promise<CreateJobResult>
Submits a voice cloning job. Returns { jobId, status, message, createdAt }.
client.getJob(jobId): Promise<VoiceCloneJob>
Returns the current job status and metadata.
client.downloadOutput(jobId): Promise<Buffer>
Downloads the completed audio as a Buffer. Only call when status === 'completed'.
client.getUsage(): Promise<Usage>
Returns { minutesLimit, minutesUsed, minutesRemaining, requestsPerDay, requestsToday }.
minutesLimit and minutesRemaining are null when the key has no quota.
Building from source
npm install
npm run build
# outputs: dist/index.js (CJS), dist/index.mjs (ESM), dist/index.d.ts (types)