Skip to main content

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 CategoryBase PathKey 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 TypeTrigger
StateChangedFolder state changes (syncing, idle, error)
FolderCompletionSync with a specific peer completed
ItemStartedA file started syncing
ItemFinishedA file finished syncing
DeviceConnectedA peer came online
DeviceDisconnectedA 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

IssueCauseFix
403 CSRF ErrorMissing X-API-Key headerAlways include -H "X-API-Key: $ST_KEY"
curl: (60) SSL certificate problemCustom self-signed certUse --cacert ~/.local/share/syncthing/https-cert.pem
404 Not Found on /rest/db/statusWrong folder IDUse the ID from config.xml, not the label
Config changes don't persistPUT to wrong endpointUse /rest/config (full config PUT) or /rest/config/folders/{id}

What's Next