Skip to content

Protocol Reference

sonic-runtime communicates over ndjson-stdio-v1 — newline-delimited JSON on stdin (commands) and stdout (responses + events).

{"id": 1, "method": "version", "params": {}}
  • id — integer, monotonically increasing, echoed in response
  • method — command name
  • params — method-specific parameters (optional)
{"id": 1, "result": {"name": "sonic-runtime", "version": "1.0.1", "protocol": "ndjson-stdio-v1"}}
{"id": 2, "error": {"code": "invalid_source", "message": "Asset file not found: /missing.wav", "retryable": false}}

The retryable field tells the caller whether retrying the same request might succeed (e.g., a temporarily unavailable device vs. a permanently invalid parameter).

{"event": "playback_ended", "data": {"handle": "h_000000000001", "reason": "completed"}}

Events have no id — they are pushed by the runtime without a prior request.

Returns runtime identity and protocol version. Used as the handshake — sonic-core hard-fails on protocol mismatch.

{"id": 2, "method": "load_asset", "params": {"asset_ref": "file:///path/to/sound.wav"}}

Loads a WAV file into an OpenAL buffer. Returns a handle for subsequent commands.

{"id": 3, "method": "play", "params": {"handle": "h_...", "volume": 0.8, "loop": true, "output_device_id": "..."}}

Starts playback. output_device_id is optional — omit for the default device.

{"id": 4, "method": "stop", "params": {"handle": "h_..."}}
{"id": 5, "method": "seek", "params": {"handle": "h_...", "position_ms": 5000}}
{"id": 6, "method": "set_volume", "params": {"handle": "h_...", "level": 0.5, "fade_ms": 200}}
{"id": 7, "method": "set_pan", "params": {"handle": "h_...", "value": -0.3, "ramp_ms": 100}}

Volume (level): 0.0-1.0. Pan (value): -1.0 (left) to 1.0 (right). Fade/ramp durations are optional.

{"id": 8, "method": "get_position", "params": {"handle": "h_..."}}
{"id": 9, "method": "get_duration", "params": {"handle": "h_..."}}

Returns position_ms or duration_ms respectively. Duration may be null for streams.

Returns all available audio output devices with their IDs, names, and default status. Device IDs are opaque strings (e.g., openal_0_a1b2c3d4) used for per-playback routing.

{"id": 10, "method": "set_device", "params": {"device_id": "openal_0_a1b2c3d4"}}
{"id": 11, "method": "synthesize", "params": {"engine": "kokoro", "voice": "af_heart", "text": "Hello world", "speed": 1.0}}

Runs TTS synthesis and returns a playable handle. engine must be “kokoro”. speed range: 0.5-2.0 (default 1.0). The result includes handle, duration_ms, sample_rate, and channels.

MethodDescription
get_healthUptime, active handles, model loaded status, voices count, eSpeak availability
get_capabilitiesSupported engines, features, protocol version, synthesis audio format
list_voicesAll loaded voice IDs with language and gender metadata
preload_modelForce-load the ONNX model (normally lazy-loaded on first synthesis)
get_model_statusWhether model is loaded, path, load time, inference count
validate_assetsCheck all synthesis assets (model, voices, eSpeak, ONNX Runtime) with actionable hints
shutdownGraceful exit
EventDataWhen
playback_endedhandle, reasonPlayback completed naturally (“completed”) or was stopped (“stopped”)
synthesis_startedhandle, engine, voiceTTS pipeline began
synthesis_completedhandle, duration_ms, inference_msTTS inference finished successfully
synthesis_failedhandle, code, messageTTS inference failed
CodeRetryableDescription
invalid_paramsnoMissing or malformed parameters
method_not_foundnoUnknown method name
playback_not_foundnoHandle does not exist
device_unavailableyesRequested device not found or unplugged
seek_unsupportednoCannot seek this source type
invalid_sourcenoOpenAL error or asset file not found
unsupported_formatnoAudio format not supported (non-PCM WAV, bad bit depth)
synthesis_validation_failednoBad engine, voice, text, or speed value
synthesis_voice_not_foundnoRequested voice ID not loaded
synthesis_model_missingnoONNX model file not found
synthesis_model_load_failednoONNX model failed to load
synthesis_inference_failedyesONNX inference error or empty output
synthesis_not_configurednoSynthesis engine not available
internal_errornoUnexpected runtime error

All human-readable diagnostic messages go to stderr, prefixed with [sonic-runtime]. stdout is reserved exclusively for protocol JSON.