Skip to content

API Reference

The Wallie server exposes a REST API over HTTP. All endpoints are available on the port your server is running on (default 9000).

No authentication is required — the API is designed for local network use. Don’t expose it to the internet.

Each frame gets a short ID assigned automatically by the server the first time it checks in. The desktop app doesn’t display this ID anywhere in the UI — the easiest way to find yours is:

Terminal window
curl -s http://192.168.1.42:9000/admin/api/frames | python3 -m json.tool

Look for the "id" field on each frame in the response.


Quick health check. Returns server version and basic counts.

Terminal window
curl http://192.168.1.42:9000/
{
"version": "1.9.1",
"running": true,
"port": 9000,
"sources": 2,
"frames": 3,
"total_images": 847
}

Returns 200 OK with {"healthy": true}. Useful for uptime monitors.

Full server status including image index state and timezone info.

{
"version": "1.9.1",
"running": true,
"frames_count": 3,
"sources_count": 2,
"total_images": 847,
"server_time": "2026-05-06T14:23:00.000Z",
"index": {
"is_scanning": false,
"initial_scan_complete": true,
"image_count": 847
}
}

Returns all registered frames with their current status. Use this to find your frame IDs.

Terminal window
curl http://192.168.1.42:9000/admin/api/frames
{
"frames": [
{
"id": "35506C",
"name": "Frame 35506C",
"battery_percentage": 72,
"usb_power_connected": false,
"firmware_version": "2.4.1",
"next_check_in": 1746540000,
"seconds_until_check_in": 3420,
"current_display": {
"image_name": "vacation-2024-001.jpg",
"served_at": "2026-05-06T10:00:00.000Z"
}
}
]
}
FieldDescription
idUnique identifier assigned by the server when the frame first checks in.
battery_percentage0–100. Only present after the frame has checked in at least once.
usb_power_connectedtrue if the frame is currently charging.
next_check_inUnix timestamp of the frame’s next scheduled check-in.
seconds_until_check_inSeconds until next check-in (convenience field).
current_display.image_nameFilename of the photo currently on the display.

Same as above for a single frame.

Terminal window
curl http://192.168.1.42:9000/admin/api/frames/35506C

Update a frame’s settings, including per-source photo order.

Terminal window
curl -X PUT http://192.168.1.42:9000/admin/api/frames/35506C \
-H "Content-Type: application/json" \
-d '{"refresh_minutes": 120}'

To change the photo rotation order for one or more sources, include a source_configs array. Each entry must have a sourceId matching an existing source and a sort_mode value:

sort_modeBehaviour
lruRotate All — shows every photo before repeating. Default.
randomShuffle — picks randomly each rotation.
newest_firstMost recently added photos first.
oldest_firstOldest photos first.
Terminal window
curl -X PUT http://192.168.1.42:9000/admin/api/frames/35506C \
-H "Content-Type: application/json" \
-d '{
"source_configs": [
{
"sourceId": "family-photos",
"sourceType": "local_folder",
"label": "Family Photos",
"enabled": true,
"weight": 1.0,
"timeHint": "anytime",
"sort_mode": "random",
"config": {}
}
]
}'

To find your sourceId values, check the sources list:

Terminal window
curl -s http://192.168.1.42:9000/admin/api/sources | python3 -m json.tool

Remove a frame from the server.

Add a photo source to a frame.

Terminal window
curl -X POST http://192.168.1.42:9000/admin/api/frames/35506C/sources \
-H "Content-Type: application/json" \
-d '{"source_id": "family-photos"}'

Get, set, or clear a pinned image for a frame. A pinned image is shown instead of the normal rotation until unpinned.


List all configured photo sources.

{
"sources": [
{
"id": "family-photos",
"type": "local_folder",
"path": "/photos/family",
"enabled": true,
"image_count": 412
}
]
}

Add a new source.

Terminal window
curl -X POST http://192.168.1.42:9000/admin/api/sources \
-H "Content-Type: application/json" \
-d '{"type": "local_folder", "path": "/photos/vacation", "enabled": true}'

Remove a source.


List indexed images. Supports filtering:

Query paramDescription
source_idFilter by source
limitMax results (default 100)
offsetPagination offset

Upload a photo directly to a source folder.

Terminal window
curl -X POST \
"http://192.168.1.42:9000/admin/api/upload?source_id=family-photos&filename=photo.jpg" \
--data-binary @photo.jpg

Remove an image from the library.

Terminal window
curl -X DELETE \
"http://192.168.1.42:9000/admin/api/delete_image?image_id=photo.jpg"

Fetch a thumbnail for an image.

Terminal window
curl "http://192.168.1.42:9000/admin/api/thumbnail?image_id=photo.jpg&width=200"

Returns recent server log output. Useful for debugging frame connectivity.


Terminal window
curl -s http://192.168.1.42:9000/admin/api/frames | \
python3 -c "
import json, sys
for f in json.load(sys.stdin)['frames']:
print(f\"{f['name']} → id: {f['id']}\")
"
Terminal window
curl -s http://192.168.1.42:9000/admin/api/frames | \
python3 -c "
import json, sys
for f in json.load(sys.stdin)['frames']:
pct = f.get('battery_percentage', 'unknown')
usb = ' (charging)' if f.get('usb_power_connected') else ''
print(f\"{f['id']}: {pct}%{usb}\")
"
#!/bin/bash
curl -s http://192.168.1.42:9000/admin/api/frames | python3 -c "
import json, sys
for f in json.load(sys.stdin)['frames']:
pct = f.get('battery_percentage')
if pct is not None and pct < 20:
print(f\"LOW BATTERY: {f['id']} is at {pct}%\")
"

Run this from a cron job to get notified before a frame goes dark.


Get or set the timezone used for wake-hour calculations. The desktop app sets this automatically; you only need this if scripting directly against the server.

Terminal window
curl -X POST http://192.168.1.42:9000/admin/api/timezone \
-H "Content-Type: application/json" \
-d '{"offset_seconds": -25200, "name": "America/Los_Angeles"}'