REST API
The Core exposes a REST API for external integrations and automation.
Authentication
REST API requests use a configurable bearer token. Enable the API and generate a token in Settings. GUI users continue to use JWT authentication.
Pass the token in the Authorization header:
Authorization: Bearer YOUR_TOKEN
Allowed actions
Fine-grained permissions control which endpoints a REST token can access:
probes_read/probes_writetests_read/tests_writeresults_readwebhooks_read
Settings, AI, certificate, and MaxMind endpoints are intentionally not reachable with a REST API token.
Authentication and authorization errors
A missing, wrong, or empty bearer token - or a disabled REST API - returns 401 with {"error":"unauthorized"}. A valid token whose required action is not enabled returns 403 with {"error":"forbidden"}. This lets an integration distinguish "my credentials are wrong" from "my credentials are fine, but this action is not allowed for this token".
OpenAPI spec
The Core serves an OpenAPI 3.1.0 specification at /openapi.json when the REST API is enabled. Download it directly with curl:
curl -s -H "Authorization: Bearer YOUR_TOKEN" \
https://core.linknesis.com/openapi.json | python3 -m json.tool
Common conventions
- All endpoints are prefixed with
/apiand served through Nginx on the HTTPS port (default 443). - Dates are returned in ISO 8601 UTC format ending with
Z. - Probe
statusreflects the live WebSocket connection state, not just the stored MongoDB value. - List endpoints are paginated with
pageandlimitquery parameters (default limit is 50).
List Probes
curl -s -H "Authorization: Bearer YOUR_TOKEN" \
https://core.linknesis.com/api/probes | python3 -m json.tool
The response contains a probes array and a total count. Use ?status=connected or ?status=disconnected to filter by connection state. Each Probe includes a version field showing the installed Probe binary version.
Get a single Probe
curl -s -H "Authorization: Bearer YOUR_TOKEN" \
https://core.linknesis.com/api/probes/PROBE_UUID | python3 -m json.tool
Update a Probe
curl -s -X PUT -H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"label":"Office Router","tags":"office,edge"}' \
https://core.linknesis.com/api/probes/PROBE_UUID | python3 -m json.tool
Only label, tags, isp, country, city, lat, and lon can be set this way; any other field in the request body is silently ignored. A request that contains none of these fields returns an error instead of a false success.
Disable, delete, and restore a Probe
Disable sets the Probe status to disabled, disconnects it, cleans up running tests, and blocks reconnections. Historical data is preserved so the Probe can be restored later.
# Disable (reversible, keeps historical data)
curl -s -X POST -H "Authorization: Bearer YOUR_TOKEN" \
https://core.linknesis.com/api/probes/PROBE_UUID/disable | python3 -m json.tool
# Restore a disabled probe (it can reconnect again)
curl -s -X POST -H "Authorization: Bearer YOUR_TOKEN" \
https://core.linknesis.com/api/probes/PROBE_UUID/restore | python3 -m json.tool
Delete is a permanent hard delete: it removes the Probe record and cascade-deletes all associated data - tests where the Probe is source or destination, test results, raw results, webhook events, AI chats, shared tests, and map positions. This cannot be undone.
# Hard delete (permanent, removes all associated data)
curl -s -X DELETE -H "Authorization: Bearer YOUR_TOKEN" \
https://core.linknesis.com/api/probes/PROBE_UUID | python3 -m json.tool
Reinstall a Probe
Force an immediate Probe reinstall regardless of the automatic Probe update toggle. The Core sends a reinstall command to the connected Probe, which downloads the matching binary from the Core API update endpoint, verifies its SHA-256 hash, and self-replaces.
curl -s -X POST -H "Authorization: Bearer YOUR_TOKEN" \
https://core.linknesis.com/api/probes/PROBE_UUID/reinstall | python3 -m json.tool
The reinstall action uses a shorter 0–5 second jitter so the Probe restarts quickly.
List tests
curl -s -H "Authorization: Bearer YOUR_TOKEN" \
"https://core.linknesis.com/api/tests?page=1&limit=25" | python3 -m json.tool
Available filters:
status-running,paused,completed, orfailedtest_type-mtroriperf3protocol-icmp,tcp, orudpprobe- source Probe UUIDdestination_probe- destination Probe UUIDtarget- target host or IPtest_id- exact test IDfrom/to- ISO 8601 UTC date range oncreated_at
Aggregate tests
Return grouped counts for the current filter set. Useful for dashboards.
curl -s -H "Authorization: Bearer YOUR_TOKEN" \
"https://core.linknesis.com/api/tests/aggregate?status=running" | python3 -m json.tool
Start a test
MTR to a public target:
curl -s -X POST -H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"probe_uuid":"SOURCE_PROBE_UUID",
"test_type":"mtr",
"target":"1.1.1.1",
"params":{
"protocol":"icmp",
"counts":10,
"interval":1,
"first_ttl":1,
"max_ttl":10,
"no_dns":true
}
}' \
https://core.linknesis.com/api/tests | python3 -m json.tool
iperf3 between two Probes (the Core starts the server on the destination):
curl -s -X POST -H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"probe_uuid":"SOURCE_PROBE_UUID",
"destination_probe":"DEST_PROBE_UUID",
"test_type":"iperf3",
"target":"DEST_PROBE_UUID",
"params":{
"protocol":"tcp",
"duration":30,
"bandwidth":10,
"parallel":1,
"reverse":false,
"bidir":false
}
}' \
https://core.linknesis.com/api/tests | python3 -m json.tool
Pause and resume a test
Pause stops execution on the Probe and saves progress offsets; resume continues the run with the remaining counts or duration.
# Pause
curl -s -X POST -H "Authorization: Bearer YOUR_TOKEN" \
https://core.linknesis.com/api/tests/TEST_ID/pause | python3 -m json.tool
# Resume
curl -s -X POST -H "Authorization: Bearer YOUR_TOKEN" \
https://core.linknesis.com/api/tests/TEST_ID/resume | python3 -m json.tool
Stop and delete a test
# Graceful stop (computes a summary from collected results)
curl -s -X POST -H "Authorization: Bearer YOUR_TOKEN" \
https://core.linknesis.com/api/tests/TEST_ID | python3 -m json.tool
# Delete a test and its results
curl -s -X DELETE -H "Authorization: Bearer YOUR_TOKEN" \
https://core.linknesis.com/api/tests/TEST_ID | python3 -m json.tool
Deleting a test also removes all related data: results, raw results, webhook events, AI chats, and public shares.
Get test results
curl -s -H "Authorization: Bearer YOUR_TOKEN" \
"https://core.linknesis.com/api/test_results?test_id=TEST_ID&page=1&limit=50" | python3 -m json.tool
Raw/underlying data (the same data used by the AI analyzer). For iperf3 tests this returns the full per-interval stream; for MTR tests it returns the current per-hop running aggregate (sent/received counts, min/avg/max/last latency, loss percentage) rather than a per-cycle history, since the Core no longer stores one:
curl -s -H "Authorization: Bearer YOUR_TOKEN" \
"https://core.linknesis.com/api/test_results_raw?test_id=TEST_ID" | python3 -m json.tool
For iperf3 tests only, the same data is also available rendered as iperf3's own classic human-readable text table (what iperf3's CLI prints without -J) instead of JSON - not available for MTR tests:
curl -s -H "Authorization: Bearer YOUR_TOKEN" \
"https://core.linknesis.com/api/test_results_iperf_text?test_id=TEST_ID"
Webhook logs
curl -s -H "Authorization: Bearer YOUR_TOKEN" \
"https://core.linknesis.com/api/webhook_logs?test_id=TEST_ID&status=sent" | python3 -m json.tool
A REST or MCP token never receives each event's webhook secret field, even with webhooks_read - a read-only integration can see delivery status and response bodies, but not the credential used to authenticate deliveries. Only the GUI's own logged-in session can see the secret.