Skip to main content

Overview

DailyTransport provides real-time audio and video communication using Daily’s hosted WebRTC platform. It handles bidirectional media streams, participant management, transcription, recording, and telephony features without requiring your own WebRTC infrastructure. Daily manages all the complexity of WebRTC connections, NAT traversal, and global media routing.

DailyTransport API Reference

Transport methods and configuration options

Example Implementation

Complete Daily transport voice agent example

Daily API Documentation

Official Daily REST API and platform documentation

Daily Dashboard

Sign up for Daily API access and room management

Installation

To use DailyTransport, install the required dependencies:

Prerequisites

Daily Account Setup

Before using DailyTransport, you need:
  1. Daily Account: Sign up at Daily Dashboard
  2. API Key: Generate a Daily API key from your dashboard
  3. Room Creation: Daily rooms must be created before connecting (see Usage section)

Required Environment Variables

  • DAILY_API_KEY: Your Daily API key for room creation and management

Key Features

  • Hosted WebRTC: No infrastructure setup required - Daily handles all WebRTC complexity
  • Multi-participant Support: Handle multiple participants with individual audio/video tracks
  • Multi-track Audio/Video: Publish multiple custom audio and video tracks simultaneously with per-track configuration, including built-in support for Daily’s screenAudio and screenVideo destinations
  • Built-in Transcription: Real-time speech-to-text with Deepgram integration
  • Telephony Integration: Dial-in/dial-out support for phone numbers via SIP/PSTN
  • Recording & Streaming: Built-in call recording and live streaming capabilities
  • Global Infrastructure: Daily’s edge network ensures low latency worldwide
  • Advanced Controls: Participant management, permissions, and media routing

Configuration

DailyTransport

str
required
URL of the Daily room to connect to.
str | None
required
Authentication token for the room, or None. Required for private rooms or when specific permissions are needed.
str
required
Display name for the bot in the call.
DailyParams
default:"DailyParams()"
Transport configuration parameters. See DailyParams below and TransportParams for inherited base parameters.
str
default:"None"
Optional name for the input transport processor.
str
default:"None"
Optional name for the output transport processor.

DailyParams

Inherits all parameters from TransportParams (audio and video settings) with these additional fields:
str
default:"https://api.daily.co/v1"
Daily API base URL.
str
default:""
Daily API authentication key. Required when dialin_settings is set.
bool
default:"True"
Receive users’ audio in separate tracks rather than a mixed stream.
DailyDialinSettings
default:"None"
Settings for dial-in functionality. See DailyDialinSettings below.
bool
default:"True"
Whether to enable the main camera output track.
Dict[str, Any]
default:"None"
Camera output track publishing settings. This dict is passed verbatim to the Daily client’s camera publishing settings, allowing full control over encoding, codec, bitrate, and framerate. See Daily VideoPublishingSettings.
Mapping[str, DailyCustomAudioTrackParams]
default:"None"
Per-destination configuration for custom audio tracks. See DailyCustomAudioTrackParams below.
Mapping[str, DailyCustomVideoTrackParams]
default:"None"
Per-destination configuration for custom video tracks. See DailyCustomVideoTrackParams below.
int | None
default:"None"
Expected download bandwidth in bits per second. The SFU starts its estimate of what it can send the bot from this value, so incoming video reaches full quality sooner. None keeps Daily’s default of 1 Mbps.
bool
default:"True"
Whether to enable the main microphone track.
bool
default:"False"
Whether to enable Daily’s built-in speech transcription (powered by Deepgram). Requires a token: without one, transcription doesn’t start and on_error fires.
DailyTranscriptionSettings
default:"DailyTranscriptionSettings()"
Configuration for the transcription service. See DailyTranscriptionSettings below.

DailyDialinSettings

Settings for Daily’s dial-in (SIP) functionality.
str
default:""
Call ID (UUID) representing the session ID in the SIP network.
str
default:""
Call domain (UUID) representing your Daily domain on the SIP network.

DailyTranscriptionSettings

Configuration for Daily’s built-in transcription service (Deepgram).
str
default:"en"
ISO language code for transcription.
str
default:"nova-2-general"
Deepgram transcription model to use.
bool
default:"True"
Whether to filter profanity from transcripts.
bool
default:"False"
Whether to redact sensitive information.
bool
default:"True"
Whether to use endpointing to determine speech segments.
bool
default:"True"
Whether to add punctuation to transcripts.
bool
default:"True"
Whether to include raw response data from Deepgram. Keep it True: with False, every transcript is pushed as an InterimTranscriptionFrame and no TranscriptionFrame reaches the pipeline.
Mapping[str, Any]
default:"{\"interim_results\": True}"
Additional parameters passed to the Deepgram transcription service.

DailyCustomAudioTrackParams

Configuration for a custom audio track. If send_settings is not provided, the track will use the default audio publishing settings (bitrate, channel config, etc.). A destination with no entry in custom_audio_track_params gets a mono track at the transport’s output sample rate.
int
default:"None"
Audio sample rate in Hz. Defaults to transport’s output sample rate.
int
default:"1"
Number of audio channels.
Dict[str, Any]
default:"None"
Optional Daily sendSettings dict for this track. See Daily AudioPublishingSettings.

DailyCustomVideoTrackParams

Configuration for a custom video track. If send_settings is not provided, the track will use the default video publishing settings (framerate, bitrate, codec, etc.). A destination with no entry in custom_video_track_params uses the transport’s video_out_width, video_out_height, and video_out_color_format.
int
default:"1024"
Video width in pixels.
int
default:"768"
Video height in pixels.
str
default:"RGB"
Video color format (e.g., “RGB”, “RGBA”, “BGRA”).
Dict[str, Any]
default:"None"
Optional Daily sendSettings dict for this track. See Daily VideoPublishingSettings.

Usage

DailyTransport connects your Pipecat bot to Daily rooms where it can communicate with participants through audio, video, and data channels. Rooms must be created using the Daily API before your bot can join. The transport integrates with Pipecat’s pipeline to process participant audio through your STT, LLM, and TTS services, then send responses back to participants. See the complete example for a full implementation including:
  • Daily room creation and token management
  • Transport configuration with transcription and VAD
  • Pipeline integration with participant event handling
  • Advanced features like recording and dial-out

Frames

Sent to the transport: When Daily rejects a transfer, REFER, or participant update, the transport pushes an ErrorFrame. OutputDTMFFrame and OutputDTMFUrgentFrame also go over Daily’s DTMF channel rather than as audio tones, to the dial-out session, else the dial-in session. Pushed by the transport: Queue a goodbye and a transfer together, and the transfer waits for the goodbye to finish playing:
For a transfer the LLM decides on, see Implementing a cold transfer.

Methods

capture_participant_transcription()

Requests Daily’s built-in transcription for a participant. Does nothing unless transcription_enabled is set; see Using built-in transcription.

capture_participant_audio()

Captures one of a participant’s audio sources ("microphone", "screenAudio", or a custom track name) and pushes it as UserAudioRawFrames with user_id set to the participant and transport_source set to audio_source. With audio_in_user_tracks=True, the default, each participant’s microphone is captured as they join, so call this for other sources. Requires audio_in_enabled=True and transport.input() in the pipeline.

capture_participant_video()

Captures one of a participant’s video sources and pushes its frames as UserImageRawFrames in color_format. The other arguments work as in Capturing video on demand. Requires video_in_enabled=True and transport.input() in the pipeline.

start_dialout()

Dials out from the room and returns (session_id, error), where error is None on success. settings takes Daily’s dial-out settings, such as phoneNumber or sipUri. The room needs dial-out enabled; see Daily PSTN and Daily SIP.

stop_dialout()

Hangs up the dial-out call to a participant and returns an error description, or None on success.

start_recording()

Starts Daily’s cloud recording and returns (stream_id, error), where error is None on success. Cloud recording must be enabled on the room or token via enable_recording; see DailyRESTHelper. The recording events are under Recording.
To record from the moment the bot joins instead, configure the meeting token with DailyRESTHelper:

stop_recording()

Stops a cloud recording and returns an error description, or None on success.

update_publishing()

Updates the bot’s publishing settings, such as camera encodings, and returns an error description, or None on success.

participants()

Returns the participants in the room as Daily reports them, keyed by participant ID, with the bot under the key "local".

Notes

Using built-in transcription

Daily can transcribe the call for you (powered by Deepgram) instead of you adding a dedicated STT service to the pipeline. Set transcription_enabled=True on DailyParams:
With this enabled, Daily runs transcription server-side and the transport pushes TranscriptionFrames into the pipeline. You do not add a separate STT service (no DeepgramSTTService, etc.) — the transport fills that role. Your bot receives the same transcriptions in-call participants see, and you can also handle them directly via the on_transcription_message event. The transport requests transcription only for participants passed to capture_participant_transcription(), so call it for each participant you want transcribed:
When to use this versus a dedicated STT service:
  • Built-in (transcription_enabled=True): one less service to wire up. Billed by Daily per participant-minute, separate from your own Deepgram key. Less control over provider and tuning.
  • Dedicated STT service in the pipeline: full control over provider, model, and settings, billed on your own provider account. This is what most Pipecat examples use. See Speech to Text.
Only enable one STT service. Enabling transcription_enabled and adding an STT processor will transcribe the same audio twice and bill you twice.

Screen Audio Destination

DailyTransport includes built-in support for Daily’s screenAudio destination. When "screenAudio" is included in the audio_out_destinations parameter, a dedicated screen audio track is automatically created when the transport starts:
Optionally configure the screenAudio track with custom parameters:

Screen Video Destination

DailyTransport includes built-in support for Daily’s screenVideo destination. When "screenVideo" is included in the video_out_destinations parameter, a dedicated screen video track is automatically created when the transport starts:

Camera Publishing Settings

The camera_out_send_settings parameter provides full control over the camera track’s publishing configuration:
The TransportParams.video_out_bitrate parameter is deprecated for Daily. Use DailyParams.camera_out_send_settings instead to configure camera publishing encodings (bitrate, framerate, codec, etc.).

Event Handlers

DailyTransport provides event handlers for room lifecycle, participant management, messaging, telephony, and recording. Register handlers using the @event_handler decorator on the transport instance.

Events Summary

Room Lifecycle

on_joined

Fired when the bot successfully joins the Daily room.
Parameters:

on_connected

Fired when the bot connects to the Daily room. This is an alias for on_joined that provides a consistent event name across all transport types.
Parameters:

on_left

Fired when the bot leaves the Daily room.
Parameters:

on_before_leave

Fired synchronously just before the bot leaves the room. Use this for cleanup that must happen before disconnection, such as stopping transcription.
Parameters:
This is a synchronous event — the bot will not leave the room until all handlers complete. Keep handlers fast.

on_error

Fired when a transport-level error occurs. It also fires once when the call ends without leave() (the bot is ejected, or the room or meeting ends). The transport then drops app messages until it joins again.
Parameters:

on_call_state_updated

Fired when the call state changes (e.g., joining, joined, leaving, left).
Parameters:

on_network_connection_status_updated

Fired when a network connection needed for the call is interrupted or connects. While the "signalling" connection is interrupted, the transport logs a warning and drops app messages until it reconnects. A failed app message is reported once as an error until a send succeeds.
Parameters:

Participants

on_first_participant_joined

Fired when the first participant (other than the bot) joins the room. This is commonly used to start the conversation.
Parameters:

on_participant_joined

Fired when any participant joins the room.
Parameters:
When a participant joins, both on_participant_joined and on_client_connected fire. Use on_first_participant_joined if you only need to react to the first participant.

on_participant_left

Fired when a participant leaves the room.
Parameters:

on_participant_updated

Fired when a participant’s state changes (e.g., audio/video tracks enabled/disabled).
Parameters:

on_client_connected / on_client_disconnected

Transport-agnostic aliases that fire alongside on_participant_joined and on_participant_left respectively, for compatibility with other transports. Both receive (transport, participant): on_client_disconnected gets no reason.

on_active_speaker_changed

Fired when the active speaker in the room changes.
Parameters:

Messaging

on_app_message

Fired when an app message is received from a participant.
Parameters:

on_transcription_message

Fired when a transcription message is received from Daily’s built-in transcription service.
Parameters:

on_transcription_stopped / on_transcription_error

Events for monitoring Daily’s built-in transcription.
Parameters:

Recording

To start and stop a recording, see start_recording() and stop_recording().

on_recording_started / on_recording_stopped / on_recording_error

Events for monitoring Daily’s built-in recording feature.
Parameters:

Telephony: Dial-in

Events for monitoring incoming phone calls. See the telephony guides for setup details.

on_dialin_ready

Fired when the dial-in SIP endpoint is ready to receive calls. If dialin_settings are configured, Pipecat automatically calls the Daily pinlessCallUpdate API.
Parameters:

on_dialin_connected / on_dialin_stopped / on_dialin_error / on_dialin_warning

Lifecycle events for dial-in calls. All receive (transport, data) where data is a dict with event details.

Telephony: Dial-out

Events for monitoring outgoing phone calls. All receive (transport, data) where data is a dict with event details.

Telephony: DTMF

on_dtmf_event

Fired when a DTMF (dual-tone multi-frequency) keypad tone is received from a phone caller. The transport automatically pushes an InputDTMFFrame into the pipeline, enabling your bot to react to keypad presses.
Parameters:
DTMF tones are automatically converted to InputDTMFFrame and pushed into the pipeline. You can handle these frames in your processors to implement IVR menus or other telephony interactions.

Additional Resources