Reading API /api/v1/logs with a stable cursor, and API tokens

GET /api/v1/logs?query=<LogsQL>&since=<cursor|time|duration>&limit=<n>
returns the logs after a cursor, oldest first, with next_cursor and
has_more. The cursor is a position on _time (the reception time) plus
the number of rows already returned among those sharing that exact
time, ordered by a hash of their content, so following the cursors
gives every row once even within groups cut by a page. Rows count once
older than the lag (30 s), and nothing is returned while the disk
spool still holds logs.

API tokens (Settings > API) give read-only access to /api/v1/ as
"Authorization: Bearer lst_...", in every auth mode; only their SHA-256
is kept in /data/api_tokens.json. README (EN/FR) documents the route and
an n8n workflow keeping the cursor in $getWorkflowStaticData.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
cedricandClaude Opus 5.5 committed 2026-11-01 15:47:57 +01:00
1 parent d61384ed2c
commit c8f45044a3
12 files changed
+1327 -7

No files matched your search

+5
View File
@@ -28,11 +28,16 @@ type API struct {
files *Files
selfLog *SelfLog
dbstats dbStatsCache
tokens *TokenStore
}
func (a *API) Routes(mux *http.ServeMux) {
mux.HandleFunc("GET /healthz", a.health)
mux.HandleFunc("GET /api/logs", a.logs)
mux.HandleFunc("GET /api/v1/logs", a.logsV1)
mux.HandleFunc("GET /api/tokens", a.listTokens)
mux.HandleFunc("POST /api/tokens", a.createToken)
mux.HandleFunc("DELETE /api/tokens/{id}", a.deleteToken)
mux.HandleFunc("GET /api/histogram", a.histogram)
mux.HandleFunc("GET /api/facets", a.facets)
mux.HandleFunc("GET /api/stream", a.stream)