-
-
Notifications
You must be signed in to change notification settings - Fork 68
API Reference
GPT Home exposes a REST API via FastAPI for the web interface and external integrations. This page documents all available endpoints, their parameters, and responses.
The FastAPI application is defined in src/backend.py and serves:
- React frontend (SPA)
- Settings management
- Event log streaming
- Integration management (Spotify, Hue, CalDAV, etc.)
- System control endpoints
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β FastAPI Backend β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββββββββββ β
β β Static Files β β API Routes β β SSE Streaming β β
β β β β β β β β
β β /static/* β β /api/settings β β /logs/stream β β
β β /favicon.ico β β /logs β β β β
β β /robot.gif β β /connect-* β β Server-Sent Events β β
β β /* (React SPA) β β /spotify-* β β Real-time log updates β β
β βββββββββββββββββββ β /hue-* β βββββββββββββββββββββββββββ β
β β /calendar-* β β
β βββββββββββββββββββ β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
-
Local network:
http://gpt-home.localorhttp://<ip-address> - Default port: 80 (handled by uvicorn via supervisor)
Read or update application settings.
Read Settings:
// Request
{
"action": "read"
}
// Response
{
"model": "gpt-4o-mini",
"temperature": 0.7,
"max_tokens": 1024,
"keyword": "computer",
"sayHeard": false,
"custom_instructions": "",
"dark_mode": true,
"litellm_api_key": "sk-..."
}Update Settings:
// Request
{
"action": "update",
"data": {
"model": "claude-3-haiku-20240307",
"temperature": 0.5,
"litellm_api_key": "sk-ant-..."
}
}
// Response - Same as read, with updated valuesToggle dark mode for the web interface.
// Request (optional - toggle)
{
"darkMode": true
}
// Response
{
"success": true,
"darkMode": true
}Get list of all models supported by LiteLLM.
// Response
{
"models": [
"gpt-4o-mini",
"gpt-4o",
"claude-3-haiku-20240307",
"gemini/gemini-1.5-flash",
...
]
}Change the active AI model.
// Request
{
"model_id": "claude-3-haiku-20240307"
}
// Response
{
"model": "claude-3-haiku-20240307"
}Get complete event logs.
// Response
{
"log_data": "INFO: Application started...\nSUCCESS: Processed query...\n..."
}Get new log entries since last check.
// Request query parameter
?last_line_number=150
// Response
{
"last_logs": ["INFO: New log entry 1", "SUCCESS: New log entry 2"],
"new_last_line_number": 152
}Server-Sent Events (SSE) stream for real-time log updates.
Event: message
Data: {"content": "INFO: Log entry", "type": "info"}
Event: ping
Data: "" (heartbeat every 15 seconds)
JavaScript Client:
const eventSource = new EventSource('/logs/stream?last_line_number=0');
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log(`[${data.type}] ${data.content}`);
};
eventSource.addEventListener('ping', () => {
console.log('Heartbeat received');
});Clear all event logs.
// Response
"Logs cleared"Clear all conversation history and stored memories. This is irreversible.
// Response (success)
{
"success": true,
"message": "Memory cleared successfully"
}
// Response (error)
{
"success": false,
"message": "Error description"
}What gets cleared:
-
checkpoints- Conversation state history -
checkpoint_blobs- Checkpoint binary data -
checkpoint_writes- Checkpoint write records -
store- All semantic and episodic memories
Get current TTS/STT capabilities based on API key provider.
// Response
{
"provider": "openai", // Detected provider or null
"tts_available": true, // LiteLLM TTS support
"stt_available": true // LiteLLM STT support
}Connect a third-party service by providing credentials.
Spotify:
// Request
{
"name": "spotify",
"fields": {
"CLIENT ID": "your-client-id",
"CLIENT SECRET": "your-client-secret"
}
}
// Response
{
"success": true
}OpenWeather:
// Request
{
"name": "openweather",
"fields": {
"API KEY": "your-api-key"
}
}
// Response
{
"success": true
}Philips Hue:
// Request
{
"name": "philipshue",
"fields": {
"BRIDGE IP ADDRESS": "192.168.1.100"
}
}
// Response
{
"success": true
}
// Note: Requires pressing bridge button within 30 secondsCalDAV:
// Request
{
"name": "caldav",
"fields": {
"URL": "https://caldav.server.com/dav/",
"USERNAME": "user",
"PASSWORD": "password"
}
}
// Response
{
"success": true
}Disconnect a third-party service.
// Request
{
"name": "spotify" // or "openweather", "philipshue", "caldav"
}
// Response
{
"success": true
}Check connection status of all services.
// Response
{
"statuses": {
"Spotify": true,
"OpenWeather": true,
"PhilipsHue": false,
"CalDAV": true
}
}Control Spotify playback.
// Request - Play/Pause
{
"text": "pause"
}
// Request - Search and play
{
"text": "play bohemian rhapsody"
}
// Request - Skip
{
"text": "next song"
}
// Response
{
"message": "Paused playback."
}Get current Spotify playback state.
// Response (playing)
{
"is_playing": true,
"track": "Song Name",
"artist": "Artist Name",
"album": "Album Name",
"album_art_url": "https://...",
"progress_ms": 30000,
"duration_ms": 180000,
"progress_pct": 0.16
}
// Response (not playing)
{
"is_playing": false
}Start the device pairing flow that signs the speaker into Spotify Connect.
// Response
{
"user_code": "ABCDEF",
"verification_url": "https://spotify.com/pair?code=ABCDEF",
"interval": 5
}Poll the pairing flow. On approval the backend stores the speaker refresh token and provisions spotifyd.
// Response (waiting)
{ "status": "pending" }
// Response (approved)
{ "status": "authorized", "message": "Speaker paired successfully!" }Report whether the speaker is paired with a Spotify account.
// Response
{ "paired": true }Note: Spotify, Philips Hue, Calendar, and Weather functionality is accessed through the LangGraph agent via voice commands, not through separate REST endpoints. The agent uses tools defined in
src/tools/to handle these integrations.
GPT Home supports HDMI, PiScreen, SPI, and I2C displays with multiple display modes.
Get current display status and capabilities.
// Response
{
"available": true,
"displays": [
{
"type": "tft_lcd",
"width": 320,
"height": 240,
"interface": "spi"
}
],
"active": true,
"current_mode": "smart"
}Set the display mode.
// Request
{
"mode": "smart" // smart, clock, weather, gallery, waveform, or off
}
// Response
{
"success": true,
"mode": "smart"
}Available Modes:
| Mode | Description |
|---|---|
smart |
Context-aware display (shows relevant info based on activity) |
clock |
Digital clock display |
weather |
Current weather conditions |
gallery |
Rotating image slideshow |
waveform |
Audio waveform visualization |
off |
Display off (blank screen) |
Waveform Behavior:
-
Architecture: Uses
WaveformMediatoras single source of truth with Observer pattern for display updates. - SMART mode: Fusion layout β always shows compact clock (upper) + voice-gated waveform bars (lower). Bars animate when speech detected, show as flat 2px lines when silent.
- WAVEFORM mode: Always shows audio visualization regardless of voice detection.
- I2C display: Always shows waveform with flat bars when silent (hidden during Spotify playback).
- Tool animation exclusion: Waveform is skipped when a tool animation is active (weather, timer, Spotify, lights, etc.).
- Screensaver: Audio activity automatically deactivates the screensaver.
Display a test message on the screen.
// Response
{
"success": true,
"message": "Test message displayed"
}Upload an image to the gallery. Accepts multipart form data.
Limits:
- Maximum file size: 50MB
- Supported formats: JPEG, PNG, GIF, BMP, WebP
Content-Type: multipart/form-data
Field: file (image file)
// Success Response
{
"success": true,
"name": "image.jpg",
"path": "/path/to/gallery/image.jpg",
"size": 102400
}
// Error Responses
// 400 - Invalid file type
{"success": false, "message": "Invalid file type: .txt"}
// 413 - File too large (nginx limit)
// Returns HTTP 413 Request Entity Too LargeDelete an image from the gallery.
// Response
{
"success": true,
"message": "Image deleted"
}Re-detect displays and reinitialize the display manager.
// Response
{
"success": true,
"message": "Display manager reinitialized"
}Attempt to power on the display (useful for HDMI standby recovery).
// Response
{
"success": true,
"message": "Power-on signal sent"
}Get detailed display debug information for troubleshooting.
// Response
{
"framebuffers": ["/dev/fb0"],
"drm_connectors": [
{"name": "HDMI-A-1", "status": "connected"}
],
"dri_devices": ["/dev/dri/card0", "/dev/dri/card1"],
"hdmi_config": {
"hdmi_force_hotplug": "1",
"hdmi_drive": "2"
}
}The screensaver is a burn-in protection layer that works across all display modes. When active, it pauses the current mode and shows an animated screensaver. User activity (voice commands, interactions) automatically deactivates it and resumes the previous display mode.
Get screensaver status and settings.
// Response
{
"success": true,
"enabled": true,
"timeout": 300,
"style": "starfield",
"is_active": false,
"current_mode": "smart",
"time_until_activation": 245.5,
"available_styles": ["starfield", "matrix", "bounce", "fade"]
}Update screensaver settings.
// Request
{
"enabled": true,
"timeout": 600,
"style": "matrix"
}
// Response
{
"success": true,
"message": "Screensaver settings updated",
"settings": {
"enabled": true,
"timeout": 600,
"style": "matrix"
}
}Available Styles:
| Style | Description |
|---|---|
starfield |
Stars flying through space (3D effect) |
matrix |
Matrix-style digital rain |
bounce |
Bouncing logo that changes color on edge hits (DVD style) |
fade |
Smooth color cycling with pulsing rings and centered clock |
Manually activate the screensaver.
// Response
{
"success": true,
"message": "Screensaver activated",
"paused_mode": "smart"
}Manually deactivate the screensaver and return to previous mode.
// Response
{
"success": true,
"message": "Screensaver deactivated",
"resumed_mode": "smart"
}Register activity to reset the screensaver inactivity timer.
// Response
{
"success": true,
"message": "Activity registered"
}Get list of available audio output devices.
// Response
{
"success": true,
"devices": [
{
"id": "hw:0,0",
"name": "bcm2835 Headphones",
"type": "alsa"
},
{
"id": "hw:1,0",
"name": "USB Audio Device",
"type": "alsa"
}
],
"current": "hw:0,0"
}Set the audio output device.
// Request
{
"device": "hw:1,0"
}
// Response
{
"success": true,
"current": "hw:1,0"
}Get current audio volume level.
// Response
{
"success": true,
"volume": 75
}Set audio volume level.
// Request
{
"volume": 80
}
// Response
{
"success": true,
"volume": 80
}Get current microphone capture gain level.
// Response
{
"gain": 80,
"card": "2"
}Set microphone capture gain level. On startup, the system auto-sets gain to 30% if it detects the current level is below 50%.
// Request
{
"gain": 80
}
// Response
{
"success": true,
"gain": 80,
"card": "2"
}Get current voice activity detection (VAD) threshold.
// Response
{
"threshold": -50.0
}Set VAD threshold in dB. Lower values = more sensitive (picks up quieter speech), higher values = less sensitive (rejects background noise). Default is -55 dB.
// Request
{
"threshold": -50
}
// Response
{
"success": true,
"threshold": -50.0
}Get current system resource usage statistics (CPU, memory, disk, network).
// Response
{
"cpu": {
"percent": [12.5, 8.3, 15.2, 10.1],
"percent_total": 11.5,
"count": 4,
"count_logical": 4,
"freq_current": 1500.0,
"freq_max": 1800.0,
"load_avg": [0.52, 0.48, 0.45]
},
"memory": {
"total": 4294967296,
"available": 2147483648,
"used": 2147483648,
"percent": 50.0,
"swap_total": 1073741824,
"swap_used": 0,
"swap_percent": 0.0
},
"disk": {
"total": 32212254720,
"used": 16106127360,
"free": 16106127360,
"percent": 50.0
},
"network": {
"bytes_sent": 1234567890,
"bytes_recv": 9876543210,
"packets_sent": 12345,
"packets_recv": 54321
},
"temperatures": {
"cpu_thermal": 45.2
},
"boot_time": 1704067200.0,
"timestamp": 1704153600.0
}Get list of running processes sorted by resource usage.
// Response
{
"processes": [
{
"pid": 1234,
"name": "python",
"cpu_percent": 15.2,
"memory_percent": 8.5,
"status": "running",
"username": "root",
"create_time": 1704067200.0
}
],
"total": 150
}Get static system information.
// Response
{
"system": "Linux",
"node": "raspberrypi",
"release": "6.1.0-rpi7-rpi-v8",
"version": "#1 SMP PREEMPT Debian 1:6.1.63-1+rpt1",
"machine": "aarch64",
"processor": "",
"python_version": "3.11.2",
"boot_time": 1704067200.0,
"uptime": 86400.0
}WebSocket endpoint providing interactive shell access to the system. Uses a PTY (pseudo-terminal) to provide a full terminal experience including support for interactive applications like vim, htop, etc.
Connection:
const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
const ws = new WebSocket(`${protocol}//${window.location.host}/api/terminal/ws`);
ws.binaryType = "arraybuffer";Sending Input:
// Send text/keystrokes to the terminal
ws.send("ls -la\n");
// Send resize event when terminal dimensions change
ws.send(JSON.stringify({
type: "resize",
rows: 24,
cols: 80
}));Receiving Output:
ws.onmessage = (event) => {
if (event.data instanceof ArrayBuffer) {
const text = new TextDecoder().decode(event.data);
terminal.write(text);
}
};Features:
- Full PTY support with ANSI color codes
- Terminal resize support
- Automatic reconnection on disconnect
- xterm-256color terminal type
Security Note: This endpoint provides shell access to the container. In production environments, ensure appropriate authentication and network security measures are in place.
// Response
{
"ip": "192.168.1.50"
}Note: This IP is displayed on connected displays and used in configuration messages to help users access the web interface.
Restart the GPT Home application container. Triggers a graceful shutdown of the app process, and Docker's restart: unless-stopped policy automatically restarts the container.
// Response
{
"success": true
}Restart the Spotifyd container via Docker.
// Response
{
"success": true
}Check if a system reboot is needed due to hardware configuration changes. Set automatically when phantom I2S devices are detected, hardware display mode changes, resolution changes, or rotation changes.
// Response
{
"reboot_needed": true,
"reason": "Stale audio overlay removed β reboot to apply changes"
}Reboot the Raspberry Pi host system (requires privileged container).
// Response
{
"success": true
}Shutdown the Raspberry Pi host system (requires privileged container).
// Response
{
"success": true
}Hash a password for storage.
// Request
{
"password": "mypassword"
}
// Response
{
"success": true,
"hashedPassword": "sha256-hash-here"
}Get the stored password hash.
// Response
{
"success": true,
"hashedPassword": "sha256-hash-here"
}Set a new password hash directly.
// Request
{
"hashedPassword": "sha256-hash-here"
}
// Response
{
"success": true
}Change password with old password verification.
// Request
{
"oldPassword": "current-password",
"newPassword": "new-password"
}
// Response (success)
{
"success": true
}
// Response (error)
HTTP 401: "Incorrect password"All endpoints return errors in a consistent format:
{
"error": "Error description",
"traceback": "Full traceback (in debug mode)"
}HTTP Status Codes:
-
200- Success -
400- Bad Request (invalid input) -
401- Unauthorized (password required) -
404- Not Found -
500- Internal Server Error
The FastAPI app is configured for local network access:
app = FastAPI()
# Static files served from React build
app.mount("/static", StaticFiles(directory="frontend/build/static"))
# SSE streaming headers
headers={
"Cache-Control": "no-cache, no-store, must-revalidate",
"Connection": "keep-alive",
"X-Accel-Buffering": "no", # Disable nginx buffering
}The main entry point for voice commands (internal):
# src/routes.py
async def action_router(
text: str,
user_id: str = "default",
thread_id: Optional[str] = None
) -> str:
"""
Main entry point for processing user requests.
Routes the text through the LangGraph agent which will:
1. Search relevant memories for context
2. Determine the appropriate tool(s) to use
3. Execute the action
4. Optionally save new memories
5. Return the response
"""This is called internally by app.py after voice recognition, not exposed as an HTTP endpoint.
- See Hardware Setup for Raspberry Pi configuration
- Check Configuration for environment variables
- Explore Development Guide for local development