Skip to content

Configuration Reference

The bridge is configured entirely from environment variables; the CLI loads a .env file from the working directory automatically (existing environment wins). The package ships a fully commented .env.example. Only three variables are required - the agent itself (LLM, tools, conversation logic) is configured where it lives, in your Line deployment on Cartesia.

EnvMeaning
WORKER_SHARED_SECRETThe shared secret from StandIn pairing. Must equal what StandIn holds, or the HMAC upgrade is rejected with 401.
CARTESIA_API_KEYServer-side Cartesia key: mints per-call access tokens and calls Sonic TTS. Never rides the agent socket.
CARTESIA_AGENT_IDThe deployed Line agent that answers calls (wss://{host}/agents/stream/{agentId}).

Your Line agent’s own deployment config is the default; these override per call:

EnvDefaultMeaning
CARTESIA_VOICE_IDunsetOverride the agent’s TTS voice (start config.voice_id).
CARTESIA_INTRODUCTIONunsetDeterministic opening line (start agent.introduction) - also the natural place for a spoken AI disclosure.
CARTESIA_SYSTEM_PROMPTunsetPrompt override (start agent.system_prompt). When set, per-call caller context (name, tenant, direction) is appended; unset = the deployed agent’s prompt, untouched. Caller context reaches your agent code via the start metadata either way.
CARTESIA_API_HOSTapi.cartesia.aiREST + agent WebSocket host. Restricted to *.cartesia.ai; CARTESIA_HOST_ALLOW_ANY=true only for a proxy you control.
CARTESIA_VERSION2025-04-16Cartesia-Version header sent on every request.
EnvDefaultMeaning
MAX_CALL_MINUTES0 (off)Bridge-side hard cap per call, in minutes (fractional allowed). Cartesia knows nothing about your budget - enforce limits here.
GOODBYE_TEXTa default lineThe goodbye the bridge-side governor speaks.
GOODBYE_GRACE_MS8000How long to let the goodbye play out before ending the call when its duration is unknown (the goodbye_request fallback). Always hard-bounded.
CARTESIA_TTS_MODELunsetEnables the deterministic goodbye via standalone Sonic TTS (exact text, agent muted, real duration honored, frames never dropped under backpressure). E.g. sonic-2.
CARTESIA_TTS_VOICE_IDunsetVoice for the goodbye TTS; falls back to CARTESIA_VOICE_ID.
CARTESIA_TTS_LANGUAGEenLanguage for the goodbye TTS.

Without a TTS model + voice, the governor goodbye is a custom {type: "goodbye_request"} event your Line agent code may speak - silent otherwise. Arming MAX_CALL_MINUTES without TTS logs a startup warning for exactly this reason. See Your Line Agent.

Keep MAX_CALL_MINUTES at 55 or less: the per-call access token is minted with the API’s maximum lifetime (1 hour) and the wire has no re-auth message, so if Cartesia enforces expiry on established streams, longer calls die abruptly at ~60 minutes. The bridge warns at startup when the limit exceeds that.

EnvDefaultMeaning
PORT8080TCP port the bridge listens on.
BIND0.0.0.0Bind address.
TLS_CERT_PATH / TLS_KEY_PATHunsetPEM cert/key for native TLS (wss://, TLS 1.2 minimum). Without both, the bridge serves plain WS and MUST be fronted by a TLS terminator.
HMAC_FRESHNESS_MS60000Allowed clock skew for the HMAC timestamp. Must be positive (0 would reject every upgrade and disable replay protection - fails loud).
MAX_CONNECTIONS0 (= 64)Max concurrent connections.
MAX_CONNECTIONS_PER_IP0 (= MAX_CONNECTIONS)Per-IP cap. Defaults to the total cap (effectively off) because StandIn dials from a small set of IPs; set explicitly (with TRUST_PROXY_XFF=true behind a proxy you control) for a real limit.
TRUST_PROXY_XFFfalseKey the per-IP cap on the first X-Forwarded-For hop. Only behind a proxy you control.
PRE_START_TIMEOUT_MS0 (= 10000)Drop a connection that authenticates but never sends session.start.
WORKER_IDLE_TIMEOUT_MS0 (= 90000)Dead-peer window: end the call after this long without any worker message (the worker heartbeats every 30 s). Frees the call id for reconnect and closes the billed agent stream.
LOG_LEVELinfodebug | info | warn | error. An invalid value falls back to info.

The bridge also exposes GET /metrics (Prometheus text format, no auth): calls total/active, a call-duration histogram (bridge_call_duration_seconds, for p50/p95/p99) plus the cumulative seconds counter, upgrade rejections by cause, frames relayed each way, backpressure drops, agent connect failures, and agent error events. Like /healthz it is served on the same port - keep the port private to your network or scrape through your ingress.

Audio formats are not configurable: the wire is PCM 16 kHz by contract and the Line stream is pinned to pcm_16000 (the copy-only property).