Inspect Agents and Runs
Discover repositories and read durable agent and runner-session metadata with a member API key.
Use a member API key with Authorization: Bearer LOBBY_API_KEY.
These source endpoints require the coordinated Auth migration/release. They are
read-only. Start and Control Agents documents opt-in
mutation keys; approval decisions remain unavailable to public keys.
| Method and path | Result |
|---|---|
GET /api/v1/repositories |
Currently accessible repositories inside key scope |
GET /api/v1/agents |
Currently permitted agents inside key scope |
GET /api/v1/agents/CONVERSATION_ID |
Agent metadata |
GET /api/v1/agents/CONVERSATION_ID/runs |
Stored runner-session history for that agent |
GET /api/v1/agents/CONVERSATION_ID/runs/RUN_ID |
One stored runner session |
Discover and inspect
Keep the key in a private file, outside Git and prompts. No browser cookie or runner capability is needed:
import json
from pathlib import Path
from urllib.parse import urlencode
from urllib.request import Request, urlopen
key = Path("lobby-api.key").read_text().strip()
def read(path):
request = Request("https://lobby.abloatai.com" + path,
headers={"Authorization": "Bearer " + key})
with urlopen(request, timeout=10) as response:
return json.load(response)
cursor = None
while True:
query = {"limit": 10}
if cursor:
query["cursor"] = cursor
page = read("/api/v1/agents?" + urlencode(query))
for agent in page["items"]:
print(agent["id"], agent["state"], agent["url"])
print(read("/api/v1/agents/" + agent["id"] + "/runs"))
cursor = page["nextCursor"]
if cursor is None:
break
Every collection returns {items: [...], nextCursor: STRING_OR_NULL}. limit
is 1–20, default 10. Pass the cursor unchanged to the same collection using the
same credential and scope. An empty page may still have nextCursor: continue
until null. Cursors are integrity-protected, expire after one hour and become
invalid after cursor-secret rotation. A 400 invalid_request requires a fresh
list. Pagination is not a snapshot; concurrent changes can alter later results.
Response fields and states
Agents return id (conversation ID), workspaceId, latestRunId, title,
visibility, adapter, model, state, createdAt, updatedAt and a direct
Lobby url. Agent state is the persisted product state: queued, running,
waiting, idle or failed. Use Workspace Status for
separate compute observation.
Runs return id, conversationId, state, startedAt, finishedAt (nullable),
activeMessageId (nullable), lastSequence, hasError and the agent’s url.
States are queued, starting, running, waiting, completed or failed.
Raw errors, runner/native identifiers and capabilities are withheld.
A run currently represents a runner session, not one prompt. Several messages
can use the same run. waiting can mean the session is idle and accepts another
message; it does not prove a coding task succeeded or an approval is pending.
hasError means the session has a stored error, which can persist after later
activity. Do not infer per-prompt success, cancellation or usage from this view.
Repositories return id, fullName, defaultBranch, private and access
(read or write). This reports current personal GitHub access intersected with
key scope; it does not authorize public lifecycle writes or validate provider
model access. Repository lists use ascending repository IDs. Models are not yet
available through this public discovery contract.
Access and errors
Each request rechecks Auth identity/membership. Agent/run reads enforce account, private visibility, current personal GitHub permissions and every repository in the workspace. Discovery workspaces with no explicit repository are denied. Revocation/removal/expiry deny subsequent requests even with a valid cursor. Reads never wake compute or probe the runner.
Responses use Cache-Control: private, no-store. Errors use the member API
envelope with X-Request-ID: 400 invalid_request, 401 unauthorized, 404
not_found (also inaccessible records), 429 rate_limited with
Retry-After: 60, or 503 auth_unavailable / unavailable. Unknown/duplicate
query fields and invalid cursor/limit values are rejected. Collections and reads
consume the same per-key verification quota as /me and workspace status.