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_write
  • tests_read / tests_write
  • results_read
  • webhooks_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 /api and served through Nginx on the HTTPS port (default 443).
  • Dates are returned in ISO 8601 UTC format ending with Z.
  • Probe status reflects the live WebSocket connection state, not just the stored MongoDB value.
  • List endpoints are paginated with page and limit query 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, or failed
  • test_type - mtr or iperf3
  • protocol - icmp, tcp, or udp
  • probe - source Probe UUID
  • destination_probe - destination Probe UUID
  • target - target host or IP
  • test_id - exact test ID
  • from / to - ISO 8601 UTC date range on created_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.

© Linknesis. Documentation for the Linknesis network monitoring platform.