Syncthing API and Scripting
Syncthing exposes a comprehensive REST API on http(s)://localhost:8384. Every GUI action can be scripted — pausing syncs, adding devices, inspecting folder state, or triggering rescan.
Learning Focus
Build workflow automations using the REST API and an API key rather than editing config.xml by hand. This is safer, idempotent, and works while Syncthing is running.
Tool Snapshot
| API Category | Base Path | Key Operations |
|---|---|---|
| System | /rest/system/ | Status, ping, restart, error log |
| Config | /rest/config/ | Devices, folders, options (GET/PUT) |
| Database | /rest/db/ | Folder status, scan, revert, browse |
| Events | /rest/events/ | Real-time event stream |
| Statistics | /rest/stats/ | Per-device and per-folder sync stats |
Getting and Using the API Key
get-api-key.sh
# Retrieve API key from config.xml
grep "<apiKey>" ~/.local/share/syncthing/config.xml
# Store it in an environment variable
export ST_KEY=$(grep -oPm1 "(?<=<apiKey>)[^<]+" ~/.local/share/syncthing/config.xml)
export ST_CERT="$HOME/.local/share/syncthing/https-cert.pem"
export ST_BASE="https://localhost:8384"
All examples below use these three variables.
Core API Operations
api-examples.sh
# 1) Ping — confirm API is reachable
curl -fs -H "X-API-Key: $ST_KEY" "$ST_BASE/rest/system/ping" --cacert "$ST_CERT"
# {"ping":"pong"}
# 2) System status
curl -fs -H "X-API-Key: $ST_KEY" "$ST_BASE/rest/system/status" --cacert "$ST_CERT" \
| jq '{version:.version, uptime:.uptime, myID:.myID}'
# 3) All configured folders
curl -fs -H "X-API-Key: $ST_KEY" "$ST_BASE/rest/config/folders" --cacert "$ST_CERT" \
| jq '.[] | {id:.id, path:.path, type:.type, state}'
# 4) All configured devices
curl -fs -H "X-API-Key: $ST_KEY" "$ST_BASE/rest/config/devices" --cacert "$ST_CERT" \
| jq '.[] | {name:.name, deviceID:.deviceID}'
# 5) Per-folder sync state
curl -fs -H "X-API-Key: $ST_KEY" \
"$ST_BASE/rest/db/status?folder=docs-sync" --cacert "$ST_CERT" \
| jq '{state:.state, needBytes:.needBytes, errors:.errors}'
# 6) Trigger a manual rescan
curl -fs -X POST -H "X-API-Key: $ST_KEY" \
"$ST_BASE/rest/db/scan?folder=docs-sync" --cacert "$ST_CERT"
# 7) Pause a folder
curl -fs -X POST -H "X-API-Key: $ST_KEY" \
"$ST_BASE/rest/db/pause?folder=docs-sync" --cacert "$ST_CERT"
# 8) Resume a folder
curl -fs -X POST -H "X-API-Key: $ST_KEY" \
"$ST_BASE/rest/db/resume?folder=docs-sync" --cacert "$ST_CERT"
# 9) Restart Syncthing
curl -fs -X POST -H "X-API-Key: $ST_KEY" \
"$ST_BASE/rest/system/restart" --cacert "$ST_CERT"
Adding a Device via API
add-device-api.sh
# Add a new trusted device
NEW_DEVICE_ID="NEW-DEVICE-XXXXXX-XXXXXX-XXXXXX-XXXXXX-XXXXXX-XXXXXX-XXXXXX"
PAYLOAD=$(cat <<EOF
{
"deviceID": "$NEW_DEVICE_ID",
"name": "new-vps-node",
"addresses": ["dynamic"],
"compression": "metadata",
"introducer": false,
"skipIntroductionRemovals": false,
"introducedBy": ""
}
EOF
)
curl -fs -X POST \
-H "X-API-Key: $ST_KEY" \
-H "Content-Type: application/json" \
-d "$PAYLOAD" \
"$ST_BASE/rest/config/devices" --cacert "$ST_CERT"
Subscribing to the Event Stream
event-stream.sh
# Follow all events in real time (long-poll)
while true; do
LAST_ID=$(curl -fs -H "X-API-Key: $ST_KEY" \
"$ST_BASE/rest/events?limit=1" --cacert "$ST_CERT" | jq '.[-1].id')
curl -fs -H "X-API-Key: $ST_KEY" \
"$ST_BASE/rest/events?since=$LAST_ID" --cacert "$ST_CERT" | jq '.[] | {type:.type, data:.data}'
sleep 1
done
Key event types to watch:
| Event Type | Trigger |
|---|---|
StateChanged | Folder state changes (syncing, idle, error) |
FolderCompletion | Sync with a specific peer completed |
ItemStarted | A file started syncing |
ItemFinished | A file finished syncing |
DeviceConnected | A peer came online |
DeviceDisconnected | A peer went offline |
Automating a Pre-Sync Hook
pre-sync-backup.sh
#!/bin/bash
# Before starting a sync, take a Restic snapshot
set -euo pipefail
echo "Taking pre-sync snapshot..."
restic backup /var/www/html/docs \
--repo /mnt/backup/syncthing \
--password-file /etc/restic-password \
--tag pre-sync \
--quiet
echo "Triggering Syncthing rescan..."
curl -fs -X POST -H "X-API-Key: $ST_KEY" \
"$ST_BASE/rest/db/scan?folder=docs-sync" --cacert "$ST_CERT"
echo "Done."
Common API Pitfalls
| Issue | Cause | Fix |
|---|---|---|
403 CSRF Error | Missing X-API-Key header | Always include -H "X-API-Key: $ST_KEY" |
curl: (60) SSL certificate problem | Custom self-signed cert | Use --cacert ~/.local/share/syncthing/https-cert.pem |
404 Not Found on /rest/db/status | Wrong folder ID | Use the ID from config.xml, not the label |
| Config changes don't persist | PUT to wrong endpoint | Use /rest/config (full config PUT) or /rest/config/folders/{id} |