Every project that used our photo-to-talking-video API ended up with the same boilerplate: start a render, poll until it's done, upload local files through a signed URL, verify the webhook signature. So I packaged it.
npm install talkpix
It has zero dependencies, runs on Node.js 18+ (built-in fetch) and ships its own TypeScript types.
Make a photo talk
import TalkPix from "talkpix";
const talkpix = new TalkPix({ apiKey: process.env.TALKPIX_API_KEY });
const video = await talkpix.videos.create({
image_url: "https://example.com/portrait.jpg",
script: "Hi! This video was made with one API call.",
voice: "zephyr",
language: "en-US",
});
const done = await talkpix.videos.waitForCompletion(video.id);
console.log(done.status, done.video_url);
waitForCompletion polls until the render is completed or failed, so you get back a finished MP4 URL or a clear error.
Use your own audio instead of a script
Swap the script for a recording and the face lip-syncs to it:
const video = await talkpix.videos.create({
image_url: "https://example.com/portrait.jpg",
audio_url: "https://example.com/voiceover.wav",
});
Upload local files
If the photo isn't at a public URL, upload it first and pass the returned key:
import { readFile } from "node:fs/promises";
const photo = await talkpix.uploadFile(await readFile("portrait.jpg"), {
contentType: "image/jpeg",
});
await talkpix.videos.create({
image_key: photo.key,
script: "Uploaded straight from my server.",
voice: "zephyr",
language: "en-US",
});
Check the cost before rendering
estimate is free and returns how many credits a script will reserve:
const { estimated_seconds, credits } = await talkpix.estimate({
script: "Happy birthday, Sam!",
});
Webhooks instead of polling
Pass a webhook_url and verify each delivery against the raw body:
import { verifyWebhookSignature } from "talkpix";
const ok = verifyWebhookSignature(
process.env.TALKPIX_WEBHOOK_SECRET,
req.get("TalkPix-Signature"),
rawBody,
);
It checks the HMAC, compares in constant time, and rejects stale timestamps.
Errors
Every API error is thrown as a TalkPixError with status, type and, for validation errors, the param that failed, so you can show users exactly which field to fix.
Links
- npm: talkpix
- Source: github.com/talkpixai/talkpix-node
- Full API reference: TalkPix developer docs
API renders use pay-as-you-go credits (packs from $5, credits don't expire, no subscription required). If you just need one video and don't want to write code, the same thing runs as a talking photo app in the browser.
Disclosure: I work on TalkPix.
Top comments (0)