Reflex Docs
Guides

Observability & data export

Pull your inference sessions, trajectory recordings, and usage straight from the API — everything your deployments produce, keyed to your API key.

Every hosted inference session Reflex runs for you is logged, recorded, and metered, and all of it is pullable with just your API key — no dashboard, no export job. Three layers:

  • Sessionswhat ran: which model, runtime, status, timing.
  • Recordingsthe data: the full trajectory (states, actions, camera video) in LeRobot format.
  • Usagethe cost: GPU time per deployment.

Everything is org-scoped: your key only ever returns your own data.

The recording methods need reflex-sdk >= 0.9.2pip install -U reflex-sdk.

Sessions — what ran

import reflex

c = reflex.Client(api_key="rfx_...")

for s in c.sessions.list()["sessions"]:
    print(s["_id"], s["baseModel"], s["status"], s.get("runtime"), s.get("closeReason"))

Each session always has _id, baseModel, status, and createdAt. Depending on the run it may also carry runtime, robotType, mode, endedAt, and closeReason — use s.get("...") for those, since they're absent until set. Filter by status — authorized, active, closing, closed, expired, or failed:

active = c.sessions.list(status="active")["sessions"]

Recordings — the trajectory data

Every session is auto-recorded in LeRobot format (states, actions, camera video) and stored org-scoped. List them, then pull one into your own storage:

recs = c.recordings.list(limit=20)["recordings"]
for r in recs:
    print(r["id"], r["sessionId"], r["formats"], r["sizeBytes"], r["status"])

# stream the dataset to disk
path = c.recordings.download(recs[0]["id"], "session.lerobot.tar")

Each recording has id, sessionId, formats (e.g. ["lerobot"]), sizeBytes, sha256, status, and createdAt. download(id, dest) mints a presigned URL and streams the dataset to dest; download_url(id) returns just the signed link if you'd rather stream it yourself.

Usage — the cost

for receipt in c.receipts.list()["receipts"]:
    print(receipt["deploymentId"], receipt["createdAt"], receipt["receiptJson"])

Pass c.receipts.list(deployment_id="...") to scope to one deployment. Each receipt carries deploymentId, createdAt, and a receiptJson payload with the metered detail.

Usage receipts populate as GPU metering rolls out per deployment. Sessions and recordings are available for every run today.

Correlating them into your database

The three layers join on the identifiers they return: a recording's sessionId matches its session's _id, and receipts carry deploymentId. A typical export pipeline:

sessions = {s["_id"]: s for s in c.sessions.list()["sessions"]}

for rec in c.recordings.list(limit=100)["recordings"]:
    session = sessions.get(rec["sessionId"])          # the run this trajectory came from
    c.recordings.download(rec["id"], f"data/{rec['sessionId']}.tar")
    save_to_your_db(session=session, recording=rec)   # your storage

API reference

CallReturns
client.sessions.list(status=None){ok, sessions: [...]}
client.recordings.list(limit=None){ok, recordings: [...]}
client.recordings.download_url(id){ok, downloadUrl}
client.recordings.download(id, dest)path written (str)
client.receipts.list(deployment_id=None){ok, receipts: [...]}

All five take only your API key and return only your org's data.