Editor handle & events
create() resolves to an editor handle — a small object you use to read what the
user made and to force a save. Alongside it, the editor emits a voxify:change DOM event so you
can react to edits in real time and pull results back into your own product.
The editor handle
The Promise returned by create() resolves with this object:
const editor = await window.VoxifyStudioEditor.create({ /* … */ });
editor.projectId // string — the current project's id
editor.flush() // force-persist the project now (Promise)
editor.getCreatives() // → Creative[] — the current creatives
editor.enhance() // run Script Enrichment on the current script (Promise)
projectId
The id of the project for this session. If you passed project.projectId it's that value;
otherwise the SDK generated a fresh one. Store it if you want to reopen the same project later.
flush()
Forces an immediate save instead of waiting for the editor's debounced autosave. Only meaningful when
persistence is enabled — with persistence off, autosave is disabled and
flush() is a no-op. Useful right before your page navigates away.
getCreatives()
Returns the current list of creatives as plain data — the simplest way to read what the user built without relying on persistence. Each creative looks like:
{
id: 'creative-uuid',
title: 'My ad',
isCurrent: true,
script: 'The full ad script…',
audioUrl: 'https://…/mix.mp3', // the rendered mix, when available
voice: { name: 'Ava', voiceId: '…', category: 'conversational' }, // or null
tracks: [
{ type: 'music', title: 'Sunrise', artist: '…', url: 'https://…' },
],
}
enhance()
Runs Script Enrichment on the current script programmatically — the same
action as the Enhance button — adding expressive performance cues and emphasis in place. Resolves with the
enriched result, or null if there's nothing to enhance.
The voxify:change event
The editor dispatches a bubbling voxify:change event on your mount element whenever the project
changes — a new script, a picked voice, a generated mix. Listen for it to keep your own UI or backend in
sync. The event detail carries the project id and the full creatives array (same shape as
getCreatives()).
const mount = document.querySelector('#voxify-script-editor-root');
mount.addEventListener('voxify:change', (e) => {
const { projectId, creatives } = e.detail;
// e.g. mirror the latest mix into your own record
const current = creatives.find(c => c.isCurrent);
if (current?.audioUrl) {
saveToMyBackend(projectId, current.audioUrl, current.script);
}
});
Recipe: capture results without persistence
A common pattern is to keep persistence off (so projects don't live in Voxify) and instead capture finished
ads into your own system. Combine the event with getCreatives():
window.VoxifyStudioEditor.create({
target: '#voxify-script-editor-root',
auth: { /* … */ },
}).then((editor) => {
const mount = document.querySelector('#voxify-script-editor-root');
// React to every change…
mount.addEventListener('voxify:change', () => {
updateSaveButtonState(editor.getCreatives());
});
// …and snapshot on demand (e.g. your own "Save" button).
document.querySelector('#my-save').addEventListener('click', () => {
saveToMyBackend(editor.projectId, editor.getCreatives());
});
});