Features / Observability

Every request of a chat, on one timeline.

Tag requests with a session id and see a whole roleplay or agent run as one timeline: models, tokens, cost and latency per step. Export it as CSV or stream it to the tracing tool you already use.

Open Sessions

What you can read

Sessions
GET /v1/sessions
requests, models, tokens, cost, errors per session
One session
GET /v1/sessions/{id}
up to 1,000 steps in order
Usage CSV
GET /v1/usage/export
up to 92 days and 200,000 rows a file
One request
GET /v1/requests/{id}
tokens and charge, plus its signed receipt

Limits you can set per key

Session caps
requests an hour, dollars
429 session_cap when reached
Loop guard
on or off
429 loop_detected on the sixth repeat in 10 minutes
Concurrency
requests in flight
Spend limit
daily, weekly or monthly
resets at 00:00 UTC, Monday or the 1st
Budget
dollars carved from the balance

Tag a session

session.sh
1curl https://api.uncensoredllm.ai/v1/chat/completions \
2 -H "Authorization: Bearer sk-ullm-live-…" \
3 -H "Content-Type: application/json" \
4 -H "x-session-id: user-42:chat-7" \
5 -d '{"model": "glm-5.3-uncensored", "messages": [{"role": "user", "content": "Hello"}]}'

Read sessions and export usage

Reading sessions and the CSV takes an admin key, created in the console; it manages keys and exports and cannot call models.

read.sh
1# Sessions, newest activity first
2curl https://api.uncensoredllm.ai/v1/sessions -H "Authorization: Bearer $ULLM_ADMIN_KEY"
3
4# Every request of one session, with tokens, cost, latency and outcome
5curl https://api.uncensoredllm.ai/v1/sessions/user-42:chat-7 -H "Authorization: Bearer $ULLM_ADMIN_KEY"
6
7# The month as CSV
8curl "https://api.uncensoredllm.ai/v1/usage/export?from=2026-10-01&to=2026-10-31" \
9 -H "Authorization: Bearer $ULLM_ADMIN_KEY" -o usage.csv

Stream traces to your backend

Add a destination once and every finished request is sent there: webhook, langfuse or otlp. Secrets are stored encrypted and never shown again.

export.sh
1curl https://api.uncensoredllm.ai/v1/exports \
2 -H "Authorization: Bearer $ULLM_ADMIN_KEY" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "kind": "otlp",
6 "name": "traces",
7 "endpoint": "https://otlp.example.com",
8 "headers": {"x-api-key": "YOUR_BACKEND_KEY"}
9 }'

Cap a session before it runs away

caps.sh
1curl -X PATCH https://api.uncensoredllm.ai/v1/keys/KEY_ID \
2 -H "Authorization: Bearer $ULLM_ADMIN_KEY" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "session_max_requests": 200,
6 "session_max_spend_usd": 2,
7 "loop_guard": true,
8 "concurrency": 8,
9 "monthly_cap_usd": 50,
10 "spend_limit_period": "weekly"
11 }'

Each request still carries its own signed receipt, checkable at /statements/verify. The console’s key dialog sets the same limits; every field is in the console docs.

Questions

Send the same x-session-id header (1 to 128 visible characters) on every request of a chat or an agent run. Without the header, x-uplink-session or a session_id or user field in the body does the same. Hosted agents group their turns on their own.

In the console under Usage → Sessions, as a timeline of every request with its model, tokens, cost, latency and outcome, or through GET /v1/sessions and /v1/sessions/{id} with an admin key.

A webhook of your own (JSON batches signed with HMAC-SHA256), Langfuse (each request as a generation, grouped by session), or any OTLP/HTTP endpoint with your headers. Batches leave within about a minute of each request and are retried on failure.

Only when you ask: include_bodies on the destination, for keys that keep request bodies. Otherwise an export carries the model, tokens, cost, latency, outcome and session, never the text.

An agent stuck repeating itself: the sixth identical tool call or request body in ten minutes is refused with 429 loop_detected. session_max_requests and session_max_spend_usd answer 429 session_cap once a session reaches them.

More features

Join on Telegram