This API provides statistics collection and retrieval services for FalconPlayer (FPP) instances. The server runs on port 7654 by default.
- Authentication
- Endpoints
- Error Handling
- Rate Limiting
- CORS
- Data Retention
- Environment Configuration
- Logging
-
Most endpoints are publicly accessible
-
Archive download requires a valid
DOWNLOAD_KEYin the URL path that is set via an environment variable. -
Upload operations require valid JSON payload structure
GET /
Redirects to the main FalconChristmas website.
Response:
- Status: 302 Redirect to
http://falconchristmas.com/
GET /health
Returns the health status of the server and GitHub API connectivity. Can be used by automatic probes to determine if GitHub API is failing.
Response Format:
{
"status": "OK|WARNING",
"github": {
"last_updated": "2026-02-14T13:24:50.829Z",
"differenceInSeconds": 9
}
}Response Details:
status: "OK" if GitHub data is recent (< 500 seconds old), "WARNING" if oldergithub.last_updated: Timestamp of last GitHub data updategithub.differenceInSeconds: Seconds since last update
Example:
curl http://localhost:7654/healthGET /status
If the server is running, returns a simple pay load. Doesn't preform any other checks like the
/health probe does.
Response Format:
{
"status": "OK"
}Example:
curl http://localhost:7654/statusGET /summary
Returns complete FPP device statistics summary including Docker and non-Docker instances.
Response Format:
{
"summary": {
"totalInstances": 1234,
"platforms": {...},
"versions": {...},
// ... extensive statistics data
},
"last_updated": "2026-02-14T13:24:50.829Z"
}Example:
curl http://localhost:7654/summaryGET /summary/{docker}
Returns FPP usage statistics filtered by Docker usage.
Parameters:
docker:"false"- Returns statistics excluding Docker instances- Any other value - Returns all statistics (same as
/summary)
Response Format:
Same as /summary endpoint but with filtered data.
Examples:
# Get stats excluding Docker instances
curl http://localhost:7654/summary/false
# Get all stats (equivalent to /summary)
curl http://localhost:7654/summary/truePOST /upload
Accepts FPP instance statistics data for collection and analysis from FPP devices.
Request Headers:
Content-Type: application/json
Request Body:
{
"uuid": "unique-instance-identifier",
"platform": "Raspberry Pi",
"version": "7.0",
// ... additional FPP instance data
}Request Validation:
- Payload must be valid JSON
- Must contain a
uuidfield - UUID must contain only alphanumeric characters and hyphens
- Maximum payload size: 100,000 bytes
- UUID format:
/^[A-Za-z0-9\-]+$/
Response Format:
{
"status": "OK|Error Message",
"uuid": "submitted-uuid"
}Response Status Values:
"OK"- Successfully uploaded"Not JSON"- Invalid JSON format"Not JSON Object"- JSON is not an object"Invalid Record"- Missing required uuid field"Invalid UUID Format"- UUID contains invalid characters"Payload too large"- Exceeds 100KB limit"Error occured during save"- Server storage error
Example:
curl -X POST \
-H "Content-Type: application/json" \
-d '{"uuid":"test-instance-123","platform":"Raspberry Pi","version":"7.0"}' \
http://localhost:7654/uploadGET /fpp_commits
Returns cached FPP Git repository branch and release information from GitHub. The branches
section outlines the last commit for every branch, while the release section can be used
to list the releaes and how my assets each has.
Response Format:
{
"branches": [
{
"name": "master",
"commit": {
"sha": "e963d9fdba67edda4ee4672f4eaa68d8f6c36da0",
"url": "https://api.github.com/repos/FalconChristmas/fpp/commits/...",
"message": "Fix compile on Pi",
"date": "2026-02-13T17:37:14Z",
"date_epoch": 1771004234
},
"protected": false
}
],
"releases": [
{
"url": "https://api.github.com/repos/FalconChristmas/fpp/releases/...",
"html_url": "https://github.com/FalconChristmas/fpp/releases/tag/9.5",
"id": 275004304,
"tag_name": "9.5",
"target_commitish": "master",
"name": "9.5",
"draft": false,
"prerelease": false,
"created_at": "2026-01-07T23:18:29Z",
"updated_at": "2026-01-24T19:30:55Z",
"published_at": "2026-01-08T03:09:40Z",
"body": "Release notes and changelog...",
"asset_cnt": 18
}
],
"last_updated": "2026-02-14T13:39:26.555Z"
}Response Details:
branches: Array of FPP Git branches with commit informationname: Branch name (e.g., "master", "v9.5")commit: Latest commit details including SHA, URL, message, and timestampsprotected: Whether the branch is protected
releases: Array of FPP GitHub releasestag_name: Release version tagname: Release display namebody: Release notes and changelogcreated_at,updated_at,published_at: Release timestampsdraft,prerelease: Release status flagsasset_cnt: Number of downloadable assets
last_updated: Timestamp when GitHub data was last cached
Example:
curl http://localhost:7654/fpp_commitsNote: This endpoint returns cached GitHub data that is periodically refreshed from the FalconChristmas/fpp repository.
GET /archive/{DOWNLOAD_KEY}
Downloads a gzipped tar archive containing all collected statistics data.
Parameters:
DOWNLOAD_KEY: Secret key required for access (configured via environment variable)
Response:
- Content-Type:
application/gzip - Content-Disposition:
attachment; filename="archive.tar.gz" - Body: gzipped tar of every
*.jsonfile in the data directory
Example:
curl -o archive.tar.gz http://localhost:7654/archive/your-secret-download-keyFreshness:
- The archive is rebuilt by the statsCollector container every 4 hours, so it can be up to 4 hours behind the most recent upload.
- If a rebuild fails the previous archive is served unchanged rather than being replaced with an unscrubbed one.
Security Notes:
- Download key must be configured in server environment
- Access is logged for security monitoring
- Records in the archive are scrubbed of identifying fields before it is built — see Data Retention
All endpoints return appropriate HTTP status codes:
200- Success302- Redirect (root endpoint)400- Bad Request (invalid data format)404- Not Found (invalid endpoint or missing file)500- Internal Server Error
Error responses typically include:
{
"status": "Error description",
"uuid": "relevant-uuid-if-applicable"
}Uploaded records are kept indefinitely — history is preserved rather than aged out. What is removed is fields, not records.
Every 4 hours, before the downloadable archive is rebuilt, the statsCollector scrubs the stored records in place:
Removed
capeInfo.serialNumberandcapeInfo.cs— together, the join key to a purchase recordcapeInfo.vendor.*— reduced toname; the block carries sole traders' personal names, e-mail, phone and postal addressesmultisync[].capeInfo.*— the same treatment for peer cape records- Any top-level block not on the allowlist — historically these have included
full
ip addroutput and lists of LAN addresses - Settings whose value is personal, a credential, or free text — replaced with
the marker
__SET__, which preserves set-vs-unset analytics
Kept
- The device
uuidand peer uuids — required for collision detection and show deduplication - Hardware, platform and version information
- Every enumerable, numeric and boolean setting
- The
consentblock recording agreement to collection
The scrub is idempotent and runs over the whole archive each time, so a policy change reaches historical records on the next pass.
There is a window: POST /upload writes the raw payload, so a record is stored
unscrubbed for up to 4 hours before the next pass. The published archive and
summary.json are built from scrubbed data.
Full detail, including the reasoning behind each keep decision, is in statsCollector/docs/SCRUBBING.md.
Required environment variables:
API_KEY: GitHub API access tokenDOWNLOAD_KEY: Secret key for archive accessport: Server port (default: 7654)
- Upload errors are logged with severity levels
- Archive downloads are logged for security
- GitHub API issues are tracked in health endpoint