Welcome to the FieldStation42 Server API! This is your one-stop guide to understanding and using the comprehensive REST API that powers your broadcasting station. Whether you're setting up your system or controlling live playback, this API has got you covered.
Quick Start
First things first - let's get your server running!
Starting the Server
python3 station_42.py
This starts both the API server and web console. Visit http://localhost:4242 to access the web interface!
Default Configuration
Your server runs with these defaults (configurable in main_config.json):
{
"server_host": "0.0.0.0",
"server_port": 4242
}
API Overview
The FieldStation42 API is organized around two main concepts:
- Build-Time APIs: System administration, configuration, and content management
- Play-Time APIs: Live player control, monitoring, and viewer interaction
All endpoints return JSON responses and follow RESTful conventions.
Build-Time APIs
For setting up your station, managing content, and system administration
Web Console
| Method | Endpoint | Description |
|---|---|---|
GET |
/ |
Main web console interface |
GET |
/remote |
Remote control interface |
Station Summary & Overview
Get Complete Station Summary
GET /summary/
Returns comprehensive overview of all stations including catalog and schedule info.
Response Example:
{
"summary_data": [
{
"network_name": "PublicDomain",
"channel_number": 1,
"catalog_summary": {
"entry_count": 42,
"total_duration": 12345.67
},
"schedule_summary": {
"network_name": "PublicDomain",
"start": "2025-07-13T00:00:00",
"end": "2025-07-14T00:00:00"
}
}
]
}
List All Stations
GET /summary/stations
Get a simple list of all station network names.
Response:
{
"network_names": ["PublicDomain", "PBS", "ClassicMovies"]
}
Schedule Management
Get Schedule Summaries
GET /summary/schedules
Returns schedule summaries for all stations.
GET /summary/schedules/{network_name}
Get schedule summary for a specific station.
Get Detailed Schedule Blocks
GET /schedules/{network_name}?start=YYYY-MM-DDTHH:MM:SS&end=YYYY-MM-DDTHH:MM:SS
Retrieve detailed schedule blocks with optional time filtering.
Example: GET /schedules/PublicDomain?start=2025-07-13T00:00:00&end=2025-07-14T00:00:00
Response:
{
"network_name": "PublicDomain",
"schedule_blocks": [
{
"content": [...],
"start_time": "2025-07-13T00:00:00",
"end_time": "2025-07-13T00:30:00",
"title": "quickstop",
"plan": [...],
"break_strategy": "standard",
"break_info": {...}
}
]
}
Catalog Management
Get All Catalog Entries
GET /catalogs/{network_name}
Search Catalog
GET /catalogs/search/{network_name}?query=search_term
Get Catalog Summaries
GET /summary/catalogs
Returns entry counts for all station catalogs.
Station Configuration
Get Station Config
GET /stations/{network_name}
Returns complete configuration for a specific station.
Themes & Styling
Get Available Themes
GET /about/themes
Lists all available CSS themes for the web interface.
To keep theme files outside the FieldStation42 directory, symlink them into the static themes directory and enable follow_static_symlinks in your main config.
Build Operations
Asynchronous operations that return task IDs for status tracking
Rebuild Catalog
POST /build/catalog/{network_name}
Rebuilds catalog for specified station (use "all" for all stations).
Returns: {"task_id": "uuid-string"}
Check Status:
GET /build/catalog/status/{task_id}
Reset Schedule
POST /build/schedule/reset/{network_name}
Completely rebuilds schedule for specified station.
Check Status:
GET /build/schedule/reset/status/{task_id}
Add Time to Schedule
POST /build/schedule/add_time/{amount}
Adds specified time period to all station schedules (e.g., "1d", "12h", "30m").
Check Status:
GET /build/schedule/add_time/status/{task_id}
Play-Time APIs
For controlling live playback and monitoring your broadcast
Player Control
Channel Control
GET /player/channels/{channel}
Change channel. Use a number, "up", or "down".
Examples:
/player/channels/5- Switch to channel 5/player/channels/up- Channel up/player/channels/down- Channel down
Show Program Guide
POST /player/channels/guide
Display the on-screen program guide.
Stop Player
GET /player/commands/stop
POST /player/commands/stop
Gracefully stop the player.
Volume Control
| Endpoint | Description |
|---|---|
GET/POST /player/volume/up |
Increase volume by 2% |
GET/POST /player/volume/down |
Decrease volume by 2% |
GET/POST /player/volume/mute |
Toggle mute on/off |
The step size is set by VOLUME_STEP in fs42/fs42_server/api/player.py.
Response Example:
{
"action": "up",
"method": "pulseaudio",
"status": "success",
"message": "Volume increased by 2%",
"volume": "75%"
}
Subtitle and Audio Tracks
| Endpoint | Description |
|---|---|
GET/POST /player/mpv/toggle-subtitles |
Show or hide subtitles |
GET/POST /player/mpv/cycle-subtitles |
Step through the available subtitle tracks |
GET/POST /player/mpv/cycle-audio |
Step through the available audio tracks |
These act on the item currently playing and do not interrupt playback. They return {"status": "ok"} once the command is queued, or 503 if the player is not connected. Both the web remote and the IR remote controller drive these same endpoints.
Parental Controls
Stations configured with parental controls hold playback behind a four-digit PIN. These endpoints feed that prompt.
| Endpoint | Description |
|---|---|
POST /player/parental/digit/{digit} |
Enter a single PIN digit |
POST /player/parental/clear |
Clear the digits entered so far |
{digit} must be a single numeric character. Anything else returns 400. Both endpoints return {"handled": true} once the command is queued, or 503 if the player is not connected.
Send one digit per request. The fourth digit completes the attempt: a correct PIN starts the station, and a wrong one clears the entry so the viewer can try again. Digits sent while no PIN prompt is on screen are ignored.
Use GET /player/status to tell whether a prompt is waiting before sending digits - this is how the IR remote controller decides whether a number press is a PIN digit or a channel change.
System Monitoring
Player Status
GET /player/status
Get current player status and program information.
The payload always includes awaiting_pin and pin_digits_entered. awaiting_pin is true while a station is holding playback behind a parental controls PIN prompt, and pin_digits_entered counts the digits accepted so far. Poll this to decide whether to route number input to /player/parental/digit/{digit} instead of a channel change.
Note that this reports the last status the player wrote. If the player exits uncleanly while a PIN prompt is on screen, awaiting_pin can remain true until the player runs again.
System Information
GET /player/info
Comprehensive system information including CPU temperature, memory usage, and load averages.
Response Example:
{
"temperature_c": 49.4,
"temperature_f": 121,
"temp_source": "vcgencmd",
"memory": {
"total_gb": 8.0,
"available_gb": 6.2,
"used_gb": 1.8,
"used_percent": 22.5
},
"cpu": {
"cores": 4,
"load_1min": 0.15,
"load_5min": 0.18,
"load_15min": 0.22,
"load_percent": 3.8
},
"system": {
"platform": "Linux",
"architecture": "aarch64",
"hostname": "fieldstation42"
}
}
Connection Status
GET /player/status/queue_connected
Check if the player command queue is connected.
Pro Tips for Developers
Date Format
Always use ISO format for date/time parameters: YYYY-MM-DDTHH:MM:SS
Asynchronous Operations
Build operations return task IDs. Always check status endpoints to monitor progress:
// Start rebuild
const response = await fetch('/build/catalog/PublicDomain', {method: 'POST'});
const {task_id} = await response.json();
// Monitor progress
const checkStatus = async () => {
const status = await fetch(`/build/catalog/status/${task_id}`);
const {status: taskStatus, log} = await status.json();
if (taskStatus === 'done') {
console.log('Rebuild complete!');
} else if (taskStatus === 'error') {
console.error('Rebuild failed:', log);
} else {
setTimeout(checkStatus, 1000); // Check again in 1 second
}
};
Volume Control
The API automatically detects and uses the best available audio system:
- PulseAudio (pactl) - Most Linux desktops
- ALSA (amixer) - Raspberry Pi and embedded systems
- WirePlumber (wpctl) - Modern PipeWire systems
Error Handling
All endpoints return detailed error messages. Always check the response:
const response = await fetch('/schedules/NonExistentStation');
if (!response.ok) {
const error = await response.json();
console.error('API Error:', error.detail);
}
Cross-Origin Requests
The server supports CORS for web development. You can make requests from any origin during development.
Example Workflows
Setting Up a New Station
- Check current stations:
GET /summary/stations - Build catalog:
POST /build/catalog/MyNewStation - Monitor progress:
GET /build/catalog/status/{task_id} - Build schedule:
POST /build/schedule/reset/MyNewStation - Verify setup:
GET /summary/
Monitoring Live Broadcast
- Check player status:
GET /player/status - Monitor system health:
GET /player/info - Control playback:
GET /player/channels/up - Adjust volume:
POST /player/volume/up
Searching and Managing Content
- Search catalog:
GET /catalogs/search/PublicDomain?query=comedy - Get schedule:
GET /schedules/PublicDomain - Add more content time:
POST /build/schedule/add_time/1d
Coming Soon
Build-Time Enhancements
- Sequence Builder:
/build/sequences/{network_name} - Breakpoint Manager:
/build/breakpoints/{network_name} - Bulk Operations: Multi-station management tools
Play-Time Features
- OSD Control:
/player/osd/display- Custom on-screen messages - Advanced Commands: System halt, safe shutdown, restart operations
- WebSocket Endpoints: Real-time status updates and live controls
- Web Console: Visit http://localhost:4242 for the graphical interface
- Source Code: Check
fs42_server.pyand theapi/directory for implementation details