Enterprise plan required
REST API access is available on the Enterprise plan. Includes full API access, higher rate limits, and dedicated support.

Quickstart

Generate your first audio file in a few minutes. This guide uses curl — see below for Node.js and PHP-style examples.

1
Get your API key
Open Voicgen dashboard → Config → API keys and create or copy a key. It starts with vg_live_.
2
Trigger audio generation
Send a POST request with your post ID and content. The post_id is your own identifier — use your CMS article ID or any unique string. Content must be at least 50 characters.
3
Poll for completion
Poll the status endpoint every few seconds until status is "ready", or use the authenticated GET /v1/audio/{post_id}/status with your API key from server-side code.
4
Use the audio URL
The status response includes an audio_url pointing to the MP3 when status is ready. Embed it in your player or download it.

Full example — curl

1. Trigger generation
curl -X POST https://api.voicgen.io/v1/audio/generate \
  -H "Content-Type: application/json" \
  -H "X-API-Key: vg_live_your_key_here" \
  -d '{
    "post_id":    "my-article-001",
    "post_title": "The future of developer tools",
    "post_url":   "https://yourblog.com/future-dev-tools",
    "content":    "<p>The future of software development is being shaped by a new wave of tools...</p>"
  }'
Response (queued)
{
  "success": true,
  "message": "Audio generation queued",
  "data": {
    "id": 1,
    "post_id": "my-article-001",
    "status": "pending",
    "progress_percent": 0,
    ...
  }
}
2. Poll status (public, no API key)
curl "https://api.voicgen.io/v1/public/audio/status?domain=yourblog.com&post_id=my-article-001&lang=en"
2b. Poll status (authenticated)
curl "https://api.voicgen.io/v1/audio/my-article-001/status?language=en" \
  -H "X-API-Key: vg_live_your_key_here"
Response when ready
{
  "success": true,
  "message": "OK",
  "data": {
    "status": "ready",
    "progress_percent": 100,
    "audio_url": "https://...",
    "duration_seconds": 142
  }
}

Node.js example

generate-audio.js
const API_KEY = process.env.VOICGEN_API_KEY
const BASE = 'https://api.voicgen.io/v1'

async function generateAudio(postId, title, content, url) {
  const res = await fetch(`${BASE}/audio/generate`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-API-Key': API_KEY,
    },
    body: JSON.stringify({
      post_id: postId,
      post_title: title,
      content,
      post_url: url,
    }),
  })

  const data = await res.json()
  if (!data.success) throw new Error(data.message)

  const domain = new URL(url).hostname
  const audioUrl = await pollPublicUntilReady(domain, postId)

  console.log('Audio ready:', audioUrl)
  return audioUrl
}

async function pollPublicUntilReady(domain, postId) {
  for (let i = 0; i < 60; i++) {
    await new Promise((r) => setTimeout(r, 3000))

    const q = new URLSearchParams({ domain, post_id: postId, lang: 'en' })
    const res = await fetch(`${BASE}/public/audio/status?${q}`)
    const data = await res.json()

    if (data.data?.status === 'ready') return data.data.audio_url
    if (data.data?.status === 'failed') throw new Error('Audio generation failed')

    console.log(`Progress: ${data.data?.progress_percent ?? 0}%`)
  }

  throw new Error('Timed out waiting for audio')
}

generateAudio(
  'my-article-001',
  'The future of developer tools',
  '<p>Your article content here (must be at least fifty characters)...</p>',
  'https://yourblog.com/future-dev-tools'
)

PHP example

generate-audio.php
<?php

$apiKey = getenv('VOICGEN_API_KEY');
$base = 'https://api.voicgen.io/v1';

function generateAudio(string $postId, string $title, string $content, string $url): string
{
    global $apiKey, $base;

    $response = wp_remote_post("{$base}/audio/generate", [
        'headers' => [
            'Content-Type' => 'application/json',
            'X-API-Key' => $apiKey,
        ],
        'body' => json_encode([
            'post_id' => $postId,
            'post_title' => $title,
            'content' => $content,
            'post_url' => $url,
        ]),
    ]);

    $data = json_decode(wp_remote_retrieve_body($response), true);
    if (!$data['success']) {
        throw new Exception($data['message']);
    }

    $domain = parse_url($url, PHP_URL_HOST);

    return pollPublicUntilReady($domain, $postId);
}

function pollPublicUntilReady(string $domain, string $postId): string
{
    global $base;

    for ($i = 0; $i < 60; $i++) {
        sleep(3);

        $response = wp_remote_get("{$base}/public/audio/status?" . http_build_query([
            'domain' => $domain,
            'post_id' => $postId,
            'lang' => 'en',
        ]));

        $data = json_decode(wp_remote_retrieve_body($response), true);

        if (($data['data']['status'] ?? '') === 'ready') {
            return $data['data']['audio_url'];
        }
        if (($data['data']['status'] ?? '') === 'failed') {
            throw new Exception('Generation failed');
        }
    }

    throw new Exception('Timed out');
}
Using the WordPress plugin?If you are on WordPress, use the WordPress plugin instead — it handles generation, polling, and player injection automatically. The REST API is for custom CMS integrations.