Dataset: AI Usage
Entity: AI Usage Measurement
Field ID: surface_ref
Type: Select list
Description: The normalised surface the usage happened on, using a closed vocabulary shared across providers so they can be compared. Possible values are:
IDE_COMPLETIONinline code completion.IDE_CHATchat in the IDE.IDE_AGENTagent mode in the IDE.CLIcommand line.CLOUD_AGENTa remote or cloud agent run.CODE_REVIEWpull request review.WEB_CHATweb chat.DESKTOP_APPdesktop application.AUTOMATIONa third-party automation.UNATTRIBUTEDreported by the provider without a surface type.
Note: Empty on TOTAL and CLIENT records, which cover several surfaces at once.
Source: Calculated
Transformation logic: Each provider's own surface vocabulary is mapped onto this shared list. The provider's raw value is always preserved in surface_name, which is the other half of the same field.
App Mapping
GitHub Copilot | Calculated: mapped from the |
Anthropic Claude (coming soon) | Calculated: mapped from |
Cursor (coming soon) | Calculated: mapped from the counter a record comes from, or from the event |
OpenAI Platform (coming soon) | Calculated: |
OpenAI Codex (coming soon) | Calculated: mapped from |
Reporting Use Cases
The Surface Ref field is what makes AI usage comparable across providers. It answers where the AI was used, in the same vocabulary whatever tool produced the record.
Where AI is actually used: Filter to
breakdown = SURFACEand group bysurface_refto see the split between completions, chat, agents, the command line and code review.Measuring the shift to agents: Tracking
IDE_AGENTandCLOUD_AGENTas a share of all interactions over time is the clearest signal of a team moving from autocomplete to agentic work.Comparing tools fairly: Because the vocabulary is shared, chat usage in Copilot and chat usage in Cursor land on the same value and can be charted side by side.
Interpreting UNATTRIBUTED: This is not an error. The provider reported usage without saying where it came from, and it is kept rather than dropped.
When it is too coarse: Several provider surfaces map onto one value. Use
surface_namewhen you need the provider's own distinction.
