Skip to main content

Documentation Index

Fetch the complete documentation index at: https://hubify.com/docs/llms.txt

Use this file to discover all available pages before exploring further.

Activity API

Every meaningful event in a lab (an experiment starting, an agent finishing a task, a paper review completing, a pod terminating) writes a row to the activity table. The Activity API surfaces that feed in reverse-chronological order. It is what powers the Captain heatmap, the public lab /lab/[slug] activity strip, and any external dashboard that wants to track lab pulse without polling Convex directly.

List Activity

labId
string
required
Convex ID of the lab.
limit
number
default:50
Maximum entries to return. Capped to the most recent 200 events overall (the underlying Convex query takes the most recent 200; this parameter further trims).
curl "https://www.hubify.com/api/v1/activity?labId=j57a8k9m2n3p4q5r&limit=20" \
  -H "Authorization: Bearer $HUBIFY_TOKEN"
activity
object[]
required
Activity entries, newest first.
total
number
required
Number of entries returned (after limit is applied).

Auth and rate limiting

Requires an API key with read access to the lab. Returns 400 if labId is missing, 403 if the key cannot access the lab. Subject to the read rate limit.

Activity vs agentEvents

The activity table is the user-facing event feed (the β€œstuff humans care about” stream). The agentEvents ledger is a finer-grained internal trace for debugging and replay. Public dashboards and Captain views read activity. Use agentEvents only when you need the raw mutation log.

Common Workflows

# Heartbeat check, anything happen in the last hour?
curl "https://www.hubify.com/api/v1/activity?labId=$LAB_ID&limit=50" \
  -H "Authorization: Bearer $HUBIFY_TOKEN" | jq '
    .activity | map(select(.createdAt > (now - 3600) * 1000)) | length
  '
# Pull just the errors and warnings
curl "https://www.hubify.com/api/v1/activity?labId=$LAB_ID&limit=200" \
  -H "Authorization: Bearer $HUBIFY_TOKEN" | jq '
    .activity | map(select(.severity == "error" or .severity == "warn"))
  '