npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

vocafuse-node

v0.1.0

Published

A Node.js SDK for communicating with the VocaFuse API and building voice-enabled applications

Readme

VocaFuse Node.js SDK

A Node.js SDK for communicating with the VocaFuse API and building voice-enabled applications.

npm version License: MIT

Features

  • ✅ Full TypeScript Support - Complete type definitions with IntelliSense
  • ✅ Dual Module Support - CommonJS and ES Modules
  • ✅ Promise-Based API - Modern async/await patterns
  • ✅ Async Iterators - Automatic pagination with for await...of
  • ✅ Auto Environment Detection - Automatic API endpoint selection based on key prefix
  • ✅ Rich Error Context - Actionable error messages with resource IDs and suggestions
  • ✅ Automatic Retries - Exponential backoff for transient failures
  • ✅ Browser Compatible - Works in Node.js and browsers
  • ✅ Zero Config - Sensible defaults with full customization
  • ✅ Webhook Verification - Built-in signature validation
  • ✅ JWT Token Generation - Frontend authentication support

Installation

npm install vocafuse-node

or with yarn:

yarn add vocafuse-node

Quick Start

import { Client } from 'vocafuse-node';

const client = new Client({
  apiKey: process.env.VOCAFUSE_API_KEY!,
  apiSecret: process.env.VOCAFUSE_API_SECRET!
});

// List voicenotes
const voicenotes = await client.voicenotes.list({ limit: 10 });
console.log(`Found ${voicenotes.data.length} voicenotes`);

// Get a specific voicenote
const voicenote = await client.voicenotes('vn_123').get();
console.log(`Status: ${voicenote.data.status}`);

// Get transcription
const transcription = await client.voicenotes('vn_123').transcription.get();
console.log(`Text: ${transcription.data.text}`);

// Delete a voicenote
await client.voicenotes('vn_123').delete();

Usage

Client Initialization

import { Client } from 'vocafuse-node';

// Basic initialization (environment auto-detected from API key prefix)
const client = new Client({
  apiKey: process.env.VOCAFUSE_API_KEY!,
  apiSecret: process.env.VOCAFUSE_API_SECRET!
});

// With custom options
const client = new Client({
  apiKey: 'sk_test_...',
  apiSecret: 'secret_...',
  timeout: 60000,
  retry: {
    maxRetries: 5,
    retryDelay: 2000
  }
});

Voicenotes

// List voicenotes with filters
const voicenotes = await client.voicenotes.list({
  status: 'transcribed',
  limit: 20,
  dateFrom: '2024-01-01'
});

// Get a specific voicenote
const voicenote = await client.voicenotes('vn_123').get();

// Delete a voicenote
await client.voicenotes('vn_123').delete();

// Get transcription (nested resource access)
const transcription = await client.voicenotes('vn_123').transcription.get();
console.log(transcription.data.text);

Automatic Pagination with Async Iterators

// Iterate over ALL voicenotes - pagination handled automatically
for await (const voicenote of client.voicenotes.iterate({ status: 'transcribed' })) {
  console.log(`Processing: ${voicenote.id}`);
}

// Collect all voicenotes into an array
const allVoicenotes = [];
for await (const voicenote of client.voicenotes.iterate()) {
  allVoicenotes.push(voicenote);
}

// Early exit stops fetching more pages
for await (const voicenote of client.voicenotes.iterate()) {
  if (voicenote.status === 'failed') {
    console.log('Found failed voicenote:', voicenote.id);
    break;
  }
}

Webhooks

// Create a webhook
const webhook = await client.webhooks.create({
  url: 'https://myapp.com/webhooks',
  events: ['voicenote.transcribed', 'voicenote.failed'],
  secret: 'my-webhook-secret'
});

// List webhooks
const webhooks = await client.webhooks.list();

// Update a webhook
await client.webhooks('wh_123').update({
  url: 'https://myapp.com/new-endpoint',
  events: ['voicenote.transcribed']
});

// Delete a webhook
await client.webhooks('wh_123').delete();

Webhook Signature Verification

import { RequestValidator } from 'vocafuse-node';

const validator = new RequestValidator(process.env.WEBHOOK_SECRET!);

// In your webhook handler
app.post('/webhooks/vocafuse', express.raw({ type: 'application/json' }), (req, res) => {
  const payload = req.body.toString('utf8');
  const signature = req.headers['x-vocafuse-signature'];

  if (!validator.validate(payload, signature)) {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  const event = JSON.parse(payload);
  // Process webhook...
  
  res.json({ received: true });
});

JWT Token Generation

import { AccessToken } from 'vocafuse-node';

const token = new AccessToken({
  apiKey: process.env.VOCAFUSE_API_KEY!,
  apiSecret: process.env.VOCAFUSE_API_SECRET!,
  identity: 'user_123'
});

// Generate token with default options
const response = await token.generate();
console.log(`Token: ${response.data.jwt_token}`);

// Generate with custom options
const customResponse = await token.generate({
  expiresIn: 3600,
  scopes: ['voicenotes:read', 'voicenotes:write']
});

API Keys

// List API keys
const keys = await client.apiKeys.list();

// Create a new API key
const newKey = await client.apiKeys.create({ name: 'Production Key' });
// Save the secret! It's only shown once
console.log(`Key: ${newKey.data.api_key}, Secret: ${newKey.data.api_secret}`);

// Delete an API key
await client.apiKeys('ak_123').delete();

Account

// Get account information
const account = await client.account.get();
console.log(`Plan: ${account.data.plan}`);
console.log(`Voicenotes: ${account.data.usage?.voicenotes_count}`);

// Update account settings
await client.account.update({
  name: 'My Company',
  settings: { default_language: 'en-US' }
});

Error Handling

The SDK provides rich, typed errors with context and suggestions:

import {
  VocaFuseError,
  VoicenoteNotFoundError,
  AuthenticationError,
  RateLimitError
} from 'vocafuse-node';

try {
  const voicenote = await client.voicenotes('vn_invalid').get();
} catch (error) {
  if (error instanceof VoicenoteNotFoundError) {
    console.error('Error:', error.message);
    // "Voicenote not found"
    
    console.error('Friendly:', error.friendlyMessage);
    // "Voicenote not found (voicenote: vn_invalid). Verify the voicenote ID exists..."
    
    console.error('Resource ID:', error.context?.resourceId);
    // "vn_invalid"
    
  } else if (error instanceof RateLimitError) {
    if (error.retryAfter) {
      await new Promise(r => setTimeout(r, error.retryAfter! * 1000));
    }
    
  } else if (error instanceof AuthenticationError) {
    console.error('Auth failed:', error.friendlyMessage);
    
  } else if (error instanceof VocaFuseError) {
    console.error('API error:', error.friendlyMessage);
  }
}

Error Types

| Error | Status Code | Description | |-------|-------------|-------------| | AuthenticationError | 401 | Invalid API credentials | | AuthorizationError | 403 | Insufficient permissions | | ValidationError | 400 | Invalid request parameters | | NotFoundError | 404 | Resource not found | | VoicenoteNotFoundError | 404 | Voicenote not found | | WebhookNotFoundError | 404 | Webhook not found | | TranscriptionNotFoundError | 404 | Transcription not found | | APIKeyNotFoundError | 404 | API key not found | | ConflictError | 409 | Resource conflict | | RateLimitError | 429 | Rate limit exceeded | | ServerError | 5xx | Server-side error |

TypeScript Support

Full TypeScript support with exported types:

import type {
  Voicenote,
  VoicenoteStatus,
  Transcription,
  Webhook,
  WebhookEvent,
  APIKey,
  Account,
  ApiResponse,
  PaginatedResponse
} from 'vocafuse-node';

Retry Configuration

The SDK automatically retries failed requests with exponential backoff:

const client = new Client({
  apiKey: '...',
  apiSecret: '...',
  retry: {
    maxRetries: 3,          // Maximum retry attempts
    retryDelay: 1000,       // Base delay in ms
    retryableStatuses: [408, 429, 500, 502, 503, 504]
  }
});

Requirements

  • Node.js 16+
  • TypeScript 4.7+ (for TypeScript users)

Support