The REST API
Every capability in Sondar is reachable over a REST API — the same surface the web UI and the CLI use. This page is the entry point, and the endpoint tables below are hand-verified against a running instance.
Base URL and authentication
Section titled “Base URL and authentication”- Base URL —
http://<host>:<port>/api/v1/…(the platform’s HTTP port, 9200 — see the ports table). - Authentication — there are two schemes, and they are not
interchangeable:
-
The JSON API is session-based.
POST /api/v1/account/loginreturns anX-Csrf-Token; send that back as a header on every subsequent call, along with the session cookie the login set. The two failures look different, and telling them apart saves the first hour:What you sent Response no session cookie at all 401 AccessDenied — Access denied, unauthenticatedthe session cookie, but no (or a stale) X-Csrf-Token403 AccessForbidden — Check Csrf Token failedThe CSRF filter only runs on requests that carry a cookie (
CsrfTokenFilter.isAccessAllowedreturns early whenWebUtils.useCookieis false), so a cookielesscurlnever reaches it — it fails authentication first. If you are hunting a “Check Csrf Token failed” that never appears, you are missing the cookie, not the token. Measured 1 Sep 2026 against a running instance. -
A collect token authenticates data going IN. Generate one under Configure → Access Control → Collection Tokens — see Collection tokens for the
defaulttoken, rotation and what to do if one leaks — and send it as anAuthorizationheader on the ingest and trace endpoints (DCTokenService.validateForIngest,TraceGateway). It is what agents and OTLP clients use; it does not authorize the JSON API.
-
Your first authenticated call
Section titled “Your first authenticated call”Three requests. The middle one is where every hand-written client goes wrong.
1. Fetch the public key. Unauthenticated, and you need it before you can log in:
curl -s http://<host>:9200/api/v1/publicKeysThe account_publicKey field is a base64 X.509 (SubjectPublicKeyInfo) RSA-2048
key.
2. Encrypt the password, then log in. The login endpoint does not take a
plain-text password by default. sondar.transport.asymmetric.encryption.enable
defaults to true, and when it is on the server RSA-decrypts the password
field before checking it. Encrypt with RSA/ECB/PKCS1Padding and base64 the
result — the Java default that EncryptionService uses:
# turn account_publicKey into a PEM file firstprintf -- '-----BEGIN PUBLIC KEY-----\n%s\n-----END PUBLIC KEY-----\n' "$KEY" > pub.pem
ENC=$(printf '%s' "$PASSWORD" | openssl pkeyutl -encrypt -pubin -inkey pub.pem \ -pkeyopt rsa_padding_mode:pkcs1 | base64 | tr -d '\n')
curl -s -c cookies.txt -X POST http://<host>:9200/api/v1/account/login \ -H 'Content-Type: application/json' \ -d "{\"username\":\"$SONDAR_USER\",\"password\":\"$ENC\"}"(base64 | tr -d '\n' rather than base64 -w0, which is GNU-only; and
$SONDAR_USER rather than $USER, which your shell already defines as the
account you are logged in as.)
The response body carries the token as X-Csrf-Token, and the session cookie
lands in cookies.txt. You need both.
The trap. Send the password in plain text and the server answers
401 AccessDenied — usernameOrPasswordIsIncorrect. The credentials are not incorrect; the payload could not be decrypted, and the endpoint reports both failures identically. If a login you are sure about keeps being rejected, check this before you check the password. An operator who wants plain-text logins for a trusted network can setsondar.transport.asymmetric.encryption.enable: falseinsondar.yml, which makes the field literal.
3. Call the API with the cookie and the token together:
curl -s -b cookies.txt -H "X-Csrf-Token: $TOKEN" \ http://<host>:9200/api/v1/reposThat returns the index list. Drop either the cookie or the token and you get one of the two failures in the table above.
The reference
Section titled “The reference”Sondar does not serve a browsable API reference, and that is deliberate rather than missing.
The bundled documentation site was dropped on 29 Jul 2026
(docs/decisions/bundled-docs-dropped.md), and with it the step that copied the
generated OpenAPI artifacts into the image. Until 13 Sep 2026 the three Swagger
routes were still registered, so /api/v1/admin/swagger rendered the real
Swagger UI shell and then returned 404 for the document it asks for — a page
that could only disappoint. Those routes are now retired: they answer exactly as
any unknown path does. That also took 43.5 MB of Swagger UI bundle out of
the image, including a second copy in a module that never served it at all.
The OpenAPI document still exists — :sondar-server:swagger generates it
into sondar-server/src/main/resources/swagger/docs/sondar.json, and a gate
(tools/check-swagger-current.sh) fails the build if it drifts from the
controllers beside it. It is simply not shipped or served.
So discover a call from the product, not from a spec browser. Every operation the web UI performs is an API call: perform it in the UI with the browser’s network tab open, and you have the method, path and body. The tables on this page cover the surface most callers need.
The API surface itself is real and large — hundreds of endpoints across search, collection, metrics, alerts, dashboards and administration — and every operation the web UI performs is one of them, which is the most reliable way to discover a call: perform it in the UI with the browser’s network tab open.
Anything under /api/v1/admin/ is behind the same session. Opening such a
path without a logged-in session returns the JSON 401 AccessDenied above, not
a login page — so fetch it from a browser tab that is already signed in, rather
than with a bare curl. (Verified 1 Sep 2026, re-checked 7 Sep 2026.)
Query language values
Section titled “Query language values”Saved searches and reports record which query language they use in splType.
Send "sonql" for a SonQL query and "interact" for one built in
Interactive Search. "spl", the name the API has always used, is accepted as a
synonym, and it is what responses still return, so clients written against it
keep working. Any other value is refused rather than guessed. A Search page link
takes the same value: /logdb/search?queryString=...&splType=sonql opens the
query in Advanced Search.
Automation
Section titled “Automation”For scripting, the CLI wraps the most common operations — search, write, and resource management — without you having to construct requests by hand. See The Sondar CLI.
Related
Section titled “Related”- Building apps and using the SDKs — extending the platform itself (custom APIs, operators, storage).
- Search — the query language behind the search API.