Skip to main content
targets.yaml says where the agent runs, how people reach it, and how much traffic to size for. Nothing about the agent’s behavior belongs here.
targets.yaml

All keys

list
required
How people reach the agent. Accepts one or more channel entries, each with a name. Required; omission is refused.
object
Traffic estimate. Accepts positive values; constraints below. Required for code targets or telephony; otherwise no traffic estimate is declared.
map
required
Target definitions selected by --target. Accepts one or more target instance names. Required; omission is refused.
string
required
Target provider. Accepts slng, livekit, pipecat, twilio. Required; omission is refused.
string
Framework version pinned in an emitted project. Accepts exact x.y.z in the supported window for LiveKit and Pipecat. Required for LiveKit and Pipecat; omit on SLNG, which emits no framework project, and on Twilio, whose app runs on no framework.
map of strings
LiveKit package overrides; other providers do not consume them. Accepts known LiveKit package names to semantic versions. If omitted, use the catalog’s package pins.
string
SDK used by an emitted project. Accepts python when written. If omitted, code targets emit Python. Omit on SLNG, which refuses this key.
string
This target’s phone route; illegal when the package has no phone use. Accepts connection file stem. If omitted, there is no phone route; required for LiveKit or Pipecat telephony.
string or list of strings
Deployment regions; more than one is LiveKit only. LiveKit accepts us-east, eu-central, or ap-south, with no duplicates. Pipecat forwards one non-empty platform region name. Both use platform placement when omitted. SLNG requires exactly one of its agent regions; omission and any are refused. See the target pages for each contract.
integer
Instances the platform holds ready, so a call is not waiting on a cold container. Accepts zero or more; Pipecat only. If omitted, no minimum is emitted; Pipecat can scale to zero.
folder path
A folder of your own Python whose respond(session) runs each agent turn. Twilio only; every other target refuses it. See Bring your own agent logic.
map
Per-target model overrides. Accepts existing model entry names to model definitions. If omitted, use the package’s model entries without overrides.
The map key is the target instance name. It is what --target takes and what names the output directory, build/<name>/. Two targets may use the same provider with different settings, for example pipecat_twilio and pipecat_telnyx. That is the whole list. channels and capacity apply to every target. A target says where the agent runs and, for a phone agent, which one connection carries the call. unmute compile compiles a project for livekit, pipecat and twilio; a slng target compiles to a deployment body instead, which Deploy to SLNG covers. A twilio project is one app you host; see the Twilio target. vapi and deepgram used to be target names too. Both are retired, and unmute validate refuses either one:
Deepgram stays a model vendor: what the refusal calls out is the target name, never the vendor.

channels

targets.yaml
channels: is a list. Each entry carries its own name, and every channel applies to every target.
string
required
What this channel is called, such as web or phone. Required; omission is refused.
string
required
Accepts realtime_audio or telephony. No kind is inferred.
boolean
Accepts true or false for telephony only. Omitted does not enable inbound calls. At least one of inbound and outbound must be true.
boolean
Accepts true or false for telephony only. Omitted does not enable outbound calls. Required as true for warm transfer or voicemail handling.
list of strings
Telephony only. Accepts cold_transfer, warm_transfer, dtmf_send, dtmf_receive, hold, hangup, voicemail_detection, and ivr_navigation; the route must support each requested control. Omit for no extra explicit requirements.
string
Accepts hangup or leave_message where supported by the route. Requires kind: telephony and outbound: true. Omit for no package-defined voicemail action.

Three rules a telephony channel brings with it

All three are enforced, fail validation, and are easier to read here than to meet by trial and error. At least one direction must be enabled. A channel with both inbound: false and outbound: false has no call leg and is refused. A warm transfer needs outbound: true. A warm transfer dials the destination itself, so the agent places a call, and a channel that only receives them cannot:
Write outbound: true even on a line people only ring in on. It describes what the agent does, not what the number is for. capacity.peak_starts_per_second becomes required. The moment any channel is telephony, the field stops being optional and must be positive:
Calls arrive in bursts and each one starts a session, so a rate is the number the compiler sizes workers from. One is a fine answer for a first line.

capacity

capacity: is a top-level key of targets.yaml and applies to every target. It is required for LiveKit and Pipecat, the two code targets. A telephony channel also makes peak_starts_per_second required.
targets.yaml
integer
required
Expected concurrent sessions at peak; must be positive. No estimate is inferred.
integer
required
Maximum concurrent sessions; must be positive and at least peak_sessions. No ceiling is inferred.
number
Required and positive for any telephony channel. Omit on a browser-only package to declare no call-start rate.
string
required
A positive Go duration, such as 5m. No duration is inferred.
The compiler turns these into worker and quota numbers, marked [unbenchmarked].

Framework versions are exact

For LiveKit and Pipecat, write all three numbers, such as 1.12.0. Unmute installs exactly what the target declares. It never widens the pin or silently upgrades it for a feature. This Unmute release supports exactly livekit-agents 1.8.8 and exactly pipecat-ai 1.12.0. Any other version is refused.

Deployment regions

deployment_region accepts one region or a list. Pipecat accepts exactly one; deploying there again means another target and agent name. LiveKit emits one lk agent create --region command per declared region. A LiveKit region is chosen when the agent is created and cannot be changed in place. LiveKit accepts us-east, eu-central, or ap-south and refuses other names. Pipecat forwards its platform’s region name as written. A model endpoint’s region is separate and stays in that model’s params or endpoint_env. See regional infrastructure for complete worker, STT, and TTS examples plus LiveKit media guidance. An empty list entry or duplicate region is an error. See the region vocabulary comparison before choosing model gateways and worker regions.

Instances held ready

With none declared the platform scales to zero when idle, so the first call after every quiet period waits for a container to start. On a phone route that wait can outrun the call: the session expires and nobody is answered at all. One instance held ready removes it, and bills for that instance whether or not anyone calls. Unmute does not write a Pipecat Cloud manifest yet, so this number reaches nothing in the build. Pass pipecat cloud deploy --min-agents 1 yourself to hold an instance ready. Pipecat only. LiveKit refuses it: LiveKit Cloud keeps the project subdomain and the agent id in livekit.toml and nothing else. A warm production replica is a property of the billing plan rather than something the compiler can write. See Pipecat over Twilio for a deployed example.

Package pins

pins is a LiveKit-only escape hatch for packages already known to the LiveKit driver. Unknown package names and versions below the catalogue floor are errors. On a pipecat target the map validates with no error, and nothing reads it. SLNG refuses a non-empty pins map. Leave it out on both targets.

models overrides

Keyed by the entry name from agent.yaml, and taking the same fields as an entry there. Use it when a target cannot run an entry as defined, or runs its own better. An override replaces the entry: a field it does not set is gone, not inherited from the base entry. Four fields are the exception. pace, endpointing_delay, semantic_endpointing, and prompt_suffix carry forward from the base entry whenever the override leaves them empty, because every target running this package wants the same turn timing and the same prompt directive. An override may replace endpointing_delay or semantic_endpointing. It cannot author pace or a different prompt_suffix.

The phone route is not here

A target names one connection and declares nothing else about how a call reaches it:
targets.yaml
The mechanism, the carrier, and the account credentials live in that one file. See connections/<name>.yaml. Three fields used to sit on the target. Writing any of them here is refused, and the refusal names the new home:
Where the target names no connection, the first two messages say in the connection file this target should name instead of a file name.

Where to go next

connections/<name>.yaml

The route: transport, carrier, and the names it needs.

Targets

What each generated project looks like.