The REST API
Nothing in the previous chapters used the web
GUI — deliberately. The GUI is a client of
Syncthing's REST API, and everything it can
show or do, a script can show or do with
curl. This chapter is the API as the lab
actually used it, which for most home purposes
is the whole of it.
The key, and the shape of a call
Every request carries the API key from
config.xml (chapter 2) in an X-API-Key
header, to the same address the GUI lives on.
Without the key, chapter 2 showed the answer:
CSRF Error, HTTP 403. With it:
$ curl -s -X GET -H "X-API-Key: $KEY" http://127.0.0.1:8385/rest/system/status
{
"myID": "VDKRCPU-UXHNS6G-4QRZCAS-TINLZ4I-UTXP2E6-37KQF7N-JTCRUFC-RRVUGAM",
"uptime": 169
}
Answers are JSON throughout — the guide pipes
several through jq, and so should you. For
plain reading in a terminal, add the HTTP
status line with -w '\n[HTTP %{http_code}]'
as the transcripts do; several useful calls
(puts, posts) answer with an empty body and a
200, and the status is the reply.
The endpoints the lab lived on
System. Who am I, who am I talking to:
GET /rest/system/ping {"ping": "pong"}
GET /rest/system/status myID, uptime, paths, versions
GET /rest/system/connections per peer: connected, address,
type, crypto, isLocal
POST /rest/system/pause pause syncing (all folders,
or ?folder=<id> for one)
POST /rest/system/resume and resume it
POST /rest/system/shutdown {"ok": "shutting down"}
Config. Read it, replace pieces of it —
this is how the lab paired devices (PUT
/rest/config/devices/<id>), created folders
(PUT /rest/config/folders/<id>), and switched
versioning on (same PUT, one field changed),
all on running instances:
GET /rest/config the whole config, as JSON
GET /rest/config/folders/<id> one folder, exactly as stored
GET /rest/config/defaults/folder
the template a new folder
starts from
GET /rest/config/options the behaviour switches
That last one repays a look in the lab, where it reads back the hermetic setup from chapter 2 — proof the switches are really off, from the running program rather than the file:
{
"globalAnnounceEnabled": false,
"localAnnounceEnabled": false,
"relaysEnabled": false,
"natEnabled": false,
"listenAddresses": [
"tcp://127.0.0.1:22005"
]
}
Database. The state of the folders themselves — the gauge cluster from chapters 3 and 8:
GET /rest/db/status?folder=<id>
state, needFiles, needBytes, localFiles,
globalFiles, localBytes, globalBytes
GET /rest/db/ignores?folder=<id>
the device's .stignore lines for the folder
POST /rest/db/revert?folder=<id>
receive-only folders: discard local changes
On ignores, one honest wrinkle from the
capture: the endpoint handed back the folder's
.stignore lines —
{
"ignore": [
"#include .stglobalignore"
],
"patterns": null
}
— the include directive as written, not the
patterns it pulls in. The lab's proof that
*.tmp and scratch were in force is the
behavioural one in chapter 5 (files that never
travelled); treat this endpoint as "show me the
ignore file," and the filesystem as the
appeal court.
Pause, used properly
The lab's last experiment is the one you will reach for in real life. Pause juniper's gazette folder, write a file on willow, wait, look:
$ curl -s -X POST -H "X-API-Key: $KEY" "http://127.0.0.1:8395/rest/system/pause?folder=gazette"
[HTTP 200]
…
$ test ! -e share-b/late-addition.txt
[exit 0]
Eight seconds — an eternity at lab speeds — and the file is not there. Pausing is not a suggestion; the folder simply stops. Resume, and the backlog flows:
$ curl -s -X POST -H "X-API-Key: $KEY" "http://127.0.0.1:8395/rest/system/resume?folder=gazette"
[HTTP 200]
$ cat share-b/late-addition.txt
A late addition, written while B was paused.
That pair of calls is the whole basis of polite automation: pause a folder before a backup snapshot, resume it after; pause the media folder before the video call, resume it at midnight.
The command-line client
One more door into the same API ships with the
binary: syncthing cli reads the address and
key from a home's config and formats the calls
for you:
$ ./bin/syncthing cli --home=home-a show system
{
…
"guiAddressUsed": "127.0.0.1:8385",
"myID": "VDKRCPU-UXHNS6G-4QRZCAS-TINLZ4I-UTXP2E6-37KQF7N-JTCRUFC-RRVUGAM",
…
}
It is the same data — one excerpt shows the
lab's fingerprints, guiAddressUsed naming
willow's port — with subcommands for showing
state, editing config, and running operations.
Between the GUI for looking, curl for
scripting, and syncthing cli for one-off
questions at a terminal, there is no fourth
thing you need to learn to run Syncthing
without a browser.
Check: curl a /rest/db/status for a
folder on your own setup and find the four
numbers from chapter 3. If you can read that
one response, you can read every gauge this
guide uses — the GUI is only ever showing you
the same numbers with better typography.