Heartbeat

A voice agent has many moving parts and almost all of them fail silently. A heartbeat endpoint is your first defense. It tells you, in one HTTP call, whether the service is up and whether FastRTC is actually importable in this environment.

router.py
python
@router.get("/health", response_model=ServiceInfo)
async def health_check():
    return ServiceInfo(
        status="ok",
        service="realtime-phone-agents-fastrtc",
        description="Realtime phone agent using FastRTC for WebRTC audio streaming",
        fastrtc_available=FASTRTC_AVAILABLE,
        webrtc_mount="/phone/webrtc",
    )

Two important fields here. fastrtc_available tells you whether the import succeeded on this host. webrtc_mount tells your client where to send the SDP offer. Both are things you want to verify before wasting time debugging audio.

models.py
python
class ServiceInfo(BaseModel):
    """Health check response"""
    status: str
    service: str
    description: str
    fastrtc_available: bool
    webrtc_mount: str

Pydantic validates the shape so a regression that drops fastrtc_available fails the response schema instead of silently passing. Health checks that lie about themselves are worse than no health checks at all.

terminal
bash
curl -s http://localhost:8000/phone/health | jq

# Expected output:
# {
#   "status": "ok",
#   "service": "realtime-phone-agents-fastrtc",
#   "description": "Realtime phone agent using FastRTC for WebRTC audio streaming",
#   "fastrtc_available": true,
#   "webrtc_mount": "/phone/webrtc"
# }

Before you touch the WebRTC client, curl the heartbeat. If fastrtc_available is false, do not chase audio bugs. Fix the import first.

Validation checklist: First connection checklist

Loading practice…

Quiz: Quiz

Loading practice…