Skip to main content

Telemetry

Workloom collects telemetry events to help you understand how packages and workspaces are used across your organization. Telemetry is opt-in via workspace policy and requires scoped API tokens for ingestion.

Overview​

The telemetry system has three components:

  1. Ingestion — batch event submission from CLI or CI
  2. Querying — retrieve raw events with filtering
  3. Summaries — aggregated counts by event type and time bucket

Event Model​

Each telemetry event contains:

FieldDescription
eventTypeDot-namespaced event name (e.g., wl.pull.completed)
workspaceIdWhich workspace this event relates to (optional)
sessionIdLogical session grouping (optional)
payloadArbitrary JSON data specific to the event type

Events are automatically stamped with the authenticated user's ID and organization.

Authentication​

Telemetry endpoints require API tokens with specific scopes:

EndpointRequired Scope
POST /telemetry/eventstelemetry:write
GET /telemetry/eventstelemetry:read
GET /telemetry/summarytelemetry:read

Create scoped tokens in Settings or via the API.

Ingesting Events​

Submit up to 100 events per request:

curl -X POST https://registry.example.com/api/v1/telemetry/events \
-H "Authorization: Bearer wl_your_token_here" \
-H "Content-Type: application/json" \
-d '{
"events": [
{
"eventType": "wl.pull.completed",
"workspaceId": "workspace-uuid",
"sessionId": "ci-run-42",
"payload": {
"packagesUpdated": 3,
"durationMs": 450,
"driftDetected": false
}
}
]
}'

Response:

{ "inserted": 1 }

Common Event Types​

Event TypeWhenExample Payload
wl.pull.completedAfter a successful wl pull{ packagesUpdated, durationMs }
wl.push.completedAfter a successful wl push{ version, scope, name }
wl.drift.detectedWhen wl status finds drift{ driftClass, targetId, path }
wl.sync.completedAfter workspace sync{ revision, changesApplied }
wl.publish.completedAfter package publish{ scope, name, version }

Querying Events​

Retrieve raw events with optional filters:

curl "https://registry.example.com/api/v1/telemetry/events?event_type=wl.drift.detected&limit=10" \
-H "Authorization: Bearer wl_your_token_here"

Filters:

  • workspace_id — scope to a single workspace
  • event_type — match a specific event type
  • cursor — paginate through results
  • limit — 1 to 100 events per page (default: 50)

Results are ordered by creation time (newest first) with cursor-based pagination.

Summaries​

Get aggregated counts grouped by event type:

curl "https://registry.example.com/api/v1/telemetry/summary?bucket=day" \
-H "Authorization: Bearer wl_your_token_here"

Bucket options:

BucketTime Range
hourLast 1 hour
dayLast 24 hours (default)
weekLast 7 days

Response:

{
"data": [
{ "eventType": "wl.pull.completed", "count": 142 },
{ "eventType": "wl.drift.detected", "count": 8 },
{ "eventType": "wl.push.completed", "count": 23 }
],
"bucket": "day"
}

CI Integration​

Add telemetry reporting to your CI pipeline:

# GitHub Actions example
- name: Pull workspace
run: wl pull

- name: Report telemetry
if: always()
run: |
curl -X POST ${{ secrets.WL_REGISTRY_URL }}/api/v1/telemetry/events \
-H "Authorization: Bearer ${{ secrets.WL_TOKEN }}" \
-H "Content-Type: application/json" \
-d "{\"events\": [{
\"eventType\": \"wl.ci.pull\",
\"workspaceId\": \"${{ vars.WL_WORKSPACE_ID }}\",
\"sessionId\": \"${{ github.run_id }}\",
\"payload\": { \"ref\": \"${{ github.ref }}\", \"sha\": \"${{ github.sha }}\" }
}]}"

Workspace Telemetry Policy​

Control telemetry at the workspace level via the telemetryPolicy field:

{
"telemetryPolicy": {
"enabled": true,
"allowedEventTypes": ["wl.pull.*", "wl.drift.*"],
"retentionDays": 90
}
}

When enabled is false, the workspace will not accept telemetry events.