Workflow Definition

The node graph behind every Onepin workflow — node types, voice mapping, script inputs, and export formats.

Every workflow is a definition: a graph of typed nodes connected by edges, plus execution settings. When you clone a template you get a ready-made graph; to change what it says, who speaks, or what format comes out, you edit node config objects. This page documents that structure.

definition
├── graph
│ ├── nodes[] — id (UUID), type, name, position, config, config_version
│ └── edges[] — id, source, sourcePort, target, targetPort
└── execution — run-time settings

Definitions are validated when saved — invalid configs are rejected at save time, and running a workflow whose required configs are empty (e.g. a cloned template with no script) fails with 422.

The authoritative, always-current schema is available from the platform itself — see Discovering schemas below. This page explains the concepts; the API is the source of truth.

Node types

typeDisplay nameWhat it does
source_scriptScript InputProvides the text — inline or from an uploaded file
processing_translatorTranslation EngineTranslates script lines into target locales
processing_generatorVoice GeneratorSynthesizes speech — this is where voices and TTS models are assigned
processing_boosterVoice Generation BoosterEnhances generation quality
validator_error_rateWord AccuracyValidates generated audio against the script; retries failures
sink_previewExportProduces the final audio files

Script Input (source_script)

Config keyMeaning
input_typeWhere the text comes from — inline text or an uploaded file
textThe script, when inline
source_languageThe script’s language (BCP-47, e.g. en-us)
upload_idsConfirmed upload IDs, when the script comes from a .txt/.docx file
1node["config"] = {"input_type": "text", "source_language": "en-us",
2 "text": "Hello from Onepin."}

To use a file instead: upload it (client.uploads.create → PUT bytes → client.uploads.confirm with context_type="workflow"), then reference the confirmed upload’s ID in upload_ids. See Uploads for the three-step flow.

Voice Generator (processing_generator)

The generator’s voice_map assigns a voice per locale:

1node["config"] = {"voice_map": {"en-us": [
2 {"voice_id": voice.provider_voice_id, # ⚠ the PROVIDER's voice id
3 "provider": "elevenlabs",
4 "model": "eleven_multilingual_v2"} # the provider's native model ID
5]}}

Two identifier traps live here:

  1. voice_id is the provider’s voice ID (provider_voice_id on a voice object), not the Onepin voice UUID you see in voices list.
  2. model is the provider’s native model ID (e.g. eleven_multilingual_v2, sonic-2) — not the Onepin catalog model IDs shown on Voices & Models. Get valid pairs from the provider catalog: client.providers.list_catalog_provider_models(provider) and .list_catalog_provider_model_voices(provider, model).

Workflows that translate into multiple locales have one generator per locale (or one voice_map entry per locale) — each needs its own voice assignment.

Word Accuracy (validator_error_rate)

Config keyDefaultRange
threshold93.070–99 (% word accuracy required to pass)
max_retries31–50 (regeneration attempts for failing lines)

This is the validation step that makes output “production-ready”: lines below the accuracy threshold are regenerated automatically before export.

Export (sink_preview)

Config keyDefaultValues
formatwavwav, mp3

The run’s downloadable export is a ZIP of the generated audio files plus a manifest.csv.

Discovering schemas

Never guess a config shape — ask the platform:

$# All node types with their input/output ports
$onepin nodes list
$
$# Full config schema + runtime options for one node type
$onepin nodes show processing_generator
$
$# JSON Schema for the entire definition (use with workflows create --definition @file.json)
$onepin workflows definition-schema

The same data is available over the API (GET /api/v1/nodes, GET /api/v1/nodes/{node_type}) and is what the canvas node-config panels are built from.

Editing a definition

The reliable pattern is read → modify → write back (definitions are replaced whole, not merged):

1definition = client.workflows.get(workflow_id=workflow_id).data.model_dump()["definition"]
2for node in definition["graph"]["nodes"]:
3 if node["type"] == "source_script":
4 node["config"] = {"input_type": "text", "source_language": "en-us", "text": "..."}
5client.workflows.patch_workflow(workflow_id, definition=definition)

The Python SDK Tutorial walks this end to end. Authoring a definition from scratch (client.workflows.create_workflow / onepin workflows create --definition @file.json) follows the same schema — start from onepin workflows definition-schema.

Estimating cost before running

$onepin workflows preview-run <WORKFLOW_ID> # estimate a run without executing it

Also available per template (GET /api/v1/templates/{id}/estimate) and via the SDK (client.workflows.preview_run, client.workflows.estimate_workflow).