Skip to main content
POST
/
v1
/
state
/
{patient_id}
/
logs
/
query
import olira
from olira import F

olira.init(api_key="YOUR_API_KEY")

# Filter, order, limit
rows = (
    olira.logs("8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82")
        .eq("type", "symptom_report")
        .gt("payload.score", 4)
        .order("timestamp", desc=True)
        .limit(50)
        .execute()
)
for row in rows:
    print(row["timestamp"], row["payload"])

# .with_count() — total_count + has_more in one request (opt-in)
rows = (
    olira.logs("8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82")
        .eq("type", "symptom_report")
        .with_count()
        .limit(50)
        .execute()
)
print(rows.total_count, rows.has_more)   # e.g. 5000, True

# Paginate through all matches (server cap: 1000/request)
offset, all_rows = 0, []
while True:
    batch = olira.logs("8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82").eq("type", "symptom_report").limit(1000).offset(offset).execute()
    all_rows.extend(batch.rows)
    if len(batch) < 1000:
        break
    offset += 1000

# Other patterns
rows = olira.logs("8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82").or_(F("payload.score").gt(7), F("type").eq("mood_report")).limit(10).execute()
n    = olira.logs("8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82").eq("type", "symptom_report").count()
row  = olira.logs("8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82").eq("type", "demographics").order("timestamp", desc=True).limit(1).maybe_single()
LogQueryResult(
    count=3,
    rows=[
        {"id": "log-1", "type": "symptom_report", "timestamp": "2026-01-14T12:00:00Z", "payload": {"score": 7}},
        {"id": "log-2", "type": "symptom_report", "timestamp": "2026-01-13T09:00:00Z", "payload": {"score": 5}},
        {"id": "log-3", "type": "symptom_report", "timestamp": "2026-01-12T08:00:00Z", "payload": {"score": 6}},
    ],
    patient_id="8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82",
    organization_id=None,
)
olira.logs(patient_id: str) -> LogQueryResult
Requires scope: sdk:state-read Chain filter, projection, ordering, and aggregation methods, then call a terminal to run: .execute() → LogQueryResult, .count() → int, .single() / .maybe_single() → dict. Filter paths must be rooted at type, timestamp, trace, or payload — other roots return 422. Add .with_count() to include total_count and has_more in the response (one extra server-side COUNT op, opt-in). Server cap: limit ≤ 1000 per request — paginate with .limit(1000).offset(n) for larger result sets.

Parameters

patient_id
str
required
Olira patient id.

Returns

LogQueryResult — Iterable, indexable result. Call .as_logs() to parse rows into typed LogEntry when no .select() was used.
count
int
Rows returned in this page.
rows
list[dict]
Projected or raw log dicts.
total_count
int | None
Total matching rows across all pages. Only set when .with_count() was used.
has_more
bool | None
True when more rows exist beyond this page. Only set when .with_count() was used.
patient_id
str | None
Echo of the queried patient id.
organization_id
str | None
Set on population queries.

Raises

ExceptionWhen
ValidationErrorUnknown operator (client-side check), or HTTP 422 from the server (invalid field root, unsupported op, limit > 1000).
AuthErrorHTTP 401 or 403 — invalid API key or insufficient OAuth scope for this endpoint.
ServerErrorHTTP 409 (e.g. conflicting external identifier) or repeated 5xx after retries; includes status_code when applicable.
RateLimitErrorHTTP 429 — rate limited; check retry_after (seconds).
NetworkErrorConnection timeout, DNS failure, or read error after retries.
import olira
from olira import F

olira.init(api_key="YOUR_API_KEY")

# Filter, order, limit
rows = (
    olira.logs("8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82")
        .eq("type", "symptom_report")
        .gt("payload.score", 4)
        .order("timestamp", desc=True)
        .limit(50)
        .execute()
)
for row in rows:
    print(row["timestamp"], row["payload"])

# .with_count() — total_count + has_more in one request (opt-in)
rows = (
    olira.logs("8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82")
        .eq("type", "symptom_report")
        .with_count()
        .limit(50)
        .execute()
)
print(rows.total_count, rows.has_more)   # e.g. 5000, True

# Paginate through all matches (server cap: 1000/request)
offset, all_rows = 0, []
while True:
    batch = olira.logs("8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82").eq("type", "symptom_report").limit(1000).offset(offset).execute()
    all_rows.extend(batch.rows)
    if len(batch) < 1000:
        break
    offset += 1000

# Other patterns
rows = olira.logs("8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82").or_(F("payload.score").gt(7), F("type").eq("mood_report")).limit(10).execute()
n    = olira.logs("8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82").eq("type", "symptom_report").count()
row  = olira.logs("8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82").eq("type", "demographics").order("timestamp", desc=True).limit(1).maybe_single()
LogQueryResult(
    count=3,
    rows=[
        {"id": "log-1", "type": "symptom_report", "timestamp": "2026-01-14T12:00:00Z", "payload": {"score": 7}},
        {"id": "log-2", "type": "symptom_report", "timestamp": "2026-01-13T09:00:00Z", "payload": {"score": 5}},
        {"id": "log-3", "type": "symptom_report", "timestamp": "2026-01-12T08:00:00Z", "payload": {"score": 6}},
    ],
    patient_id="8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82",
    organization_id=None,
)