POST
/
api
/
v1
/
Analytics
Custom Analytics Query
curl --request POST \
  --url https://server.codeium.com/api/v1/Analytics \
  --header 'Content-Type: application/json' \
  --data '{
  "service_key": "<string>",
  "group_name": "<string>",
  "query_requests": [
    {}
  ],
  "data_source": "<string>",
  "selections": [
    {}
  ],
  "filters": [
    {}
  ],
  "aggregations": [
    {}
  ],
  "field": "<string>",
  "name": "<string>",
  "aggregation_function": "<string>",
  "value": "<string>",
  "filter": "<string>"
}'
{
  "queryResults": [
    {
      "responseItems": [
        {
          "item": {}
        }
      ]
    }
  ]
}

Overview

The Custom Analytics API provides flexible querying capabilities for autocomplete, chat, and command data with customizable selections, filters, aggregations, and orderings.

Request

service_key
string
required
Your service key with “Teams Read-only” permissions
group_name
string
Filter results to users in a specific group (optional)
query_requests
array
required
Array of query request objects defining the data to retrieve

Query Request Structure

Each query request object contains:
data_source
string
required
Data source to query. Options:
  • QUERY_DATA_SOURCE_USER_DATA - Autocomplete data
  • QUERY_DATA_SOURCE_CHAT_DATA - Chat data
  • QUERY_DATA_SOURCE_COMMAND_DATA - Command data
  • QUERY_DATA_SOURCE_PCW_DATA - Percent Code Written data
selections
array
required
Array of field selections to retrieve (see Selections section)
filters
array
Array of filters to apply (see Filters section)
aggregations
array
Array of aggregations to group by (see Aggregations section)

Selections

Selections define which fields to retrieve and how to aggregate them.
field
string
required
Field name to select (see Available Fields section)
name
string
Alias for the field. If not specified, defaults to {aggregation_function}_{field_name} (lowercase)
aggregation_function
string
Aggregation function to apply:
  • QUERY_AGGREGATION_UNSPECIFIED (default)
  • QUERY_AGGREGATION_COUNT
  • QUERY_AGGREGATION_SUM
  • QUERY_AGGREGATION_AVG
  • QUERY_AGGREGATION_MAX
  • QUERY_AGGREGATION_MIN

Selection Example

{
  "field": "num_acceptances",
  "name": "total_acceptances",
  "aggregation_function": "QUERY_AGGREGATION_SUM"
}

Filters

Filters narrow down data to elements meeting specific criteria.
name
string
required
Field name to filter on
value
string
required
Value to compare against
filter
string
required
Filter operation:
  • QUERY_FILTER_EQUAL
  • QUERY_FILTER_NOT_EQUAL
  • QUERY_FILTER_GREATER_THAN
  • QUERY_FILTER_LESS_THAN
  • QUERY_FILTER_GE (greater than or equal)
  • QUERY_FILTER_LE (less than or equal)

Filter Example

{
  "name": "language",
  "filter": "QUERY_FILTER_EQUAL",
  "value": "PYTHON"
}

Aggregations

Aggregations group data by specified criteria.
field
string
required
Field name to group by
name
string
required
Alias for the aggregation field

Aggregation Example

{
  "field": "ide",
  "name": "ide_type"
}

Available Fields

User Data

All User Data is aggregated per user, per hour.
Field NameDescriptionValid Aggregations
api_keyHash of user API keyUNSPECIFIED, COUNT
dateUTC date of autocompletionUNSPECIFIED, COUNT
date UTC-xDate with timezone offset (e.g., “date UTC-8” for PST)UNSPECIFIED, COUNT
hourUTC hour of autocompletionUNSPECIFIED, COUNT
languageProgramming languageUNSPECIFIED, COUNT
ideIDE being usedUNSPECIFIED, COUNT
versionWindsurf versionUNSPECIFIED, COUNT
num_acceptancesNumber of autocomplete acceptancesSUM, MAX, MIN, AVG
num_lines_acceptedLines of code acceptedSUM, MAX, MIN, AVG
num_bytes_acceptedBytes acceptedSUM, MAX, MIN, AVG
distinct_usersDistinct usersUNSPECIFIED, COUNT
distinct_developer_daysDistinct (user, day) tuplesUNSPECIFIED, COUNT
distinct_developer_hoursDistinct (user, hour) tuplesUNSPECIFIED, COUNT

Chat Data

All Chat Data represents chat model responses, not user questions.
Field NameDescriptionValid Aggregations
api_keyHash of user API keyUNSPECIFIED, COUNT
model_idChat model IDUNSPECIFIED, COUNT
dateUTC date of chat responseUNSPECIFIED, COUNT
date UTC-xDate with timezone offsetUNSPECIFIED, COUNT
ideIDE being usedUNSPECIFIED, COUNT
versionWindsurf versionUNSPECIFIED, COUNT
latest_intent_typeChat intent type (see Intent Types below)UNSPECIFIED, COUNT
num_chats_receivedNumber of chat messages receivedSUM, MAX, MIN, AVG
chat_acceptedWhether chat was accepted (thumbs up)SUM, COUNT
chat_inserted_at_cursorWhether “Insert” button was clickedSUM, COUNT
chat_appliedWhether “Apply Diff” button was clickedSUM, COUNT
chat_loc_usedLines of code used from chatSUM, MAX, MIN, AVG

Chat Intent Types

  • CHAT_INTENT_GENERIC - Regular chat
  • CHAT_INTENT_FUNCTION_EXPLAIN - Function explanation code lens
  • CHAT_INTENT_FUNCTION_DOCSTRING - Function docstring code lens
  • CHAT_INTENT_FUNCTION_REFACTOR - Function refactor code lens
  • CHAT_INTENT_CODE_BLOCK_EXPLAIN - Code block explanation code lens
  • CHAT_INTENT_CODE_BLOCK_REFACTOR - Code block refactor code lens
  • CHAT_INTENT_PROBLEM_EXPLAIN - Problem explanation code lens
  • CHAT_INTENT_FUNCTION_UNIT_TESTS - Function unit tests code lens

Command Data

Command Data includes all commands, including declined ones. Use the accepted field to filter for accepted commands only.
Field NameDescriptionValid Aggregations
api_keyHash of user API keyUNSPECIFIED, COUNT
dateUTC date of commandUNSPECIFIED, COUNT
timestampUTC timestamp of commandUNSPECIFIED, COUNT
languageProgramming languageUNSPECIFIED, COUNT
ideIDE being usedUNSPECIFIED, COUNT
versionWindsurf versionUNSPECIFIED, COUNT
command_sourceCommand trigger source (see Command Sources below)UNSPECIFIED, COUNT
provider_sourceGeneration or edit modeUNSPECIFIED, COUNT
lines_addedLines of code addedSUM, MAX, MIN, AVG
lines_removedLines of code removedSUM, MAX, MIN, AVG
bytes_addedBytes addedSUM, MAX, MIN, AVG
bytes_removedBytes removedSUM, MAX, MIN, AVG
selection_linesLines selected (zero for generations)SUM, MAX, MIN, AVG
selection_bytesBytes selected (zero for generations)SUM, MAX, MIN, AVG
acceptedWhether command was acceptedSUM, COUNT

Command Sources

  • COMMAND_REQUEST_SOURCE_LINE_HINT_CODE_LENS
  • COMMAND_REQUEST_SOURCE_DEFAULT - Typical command usage
  • COMMAND_REQUEST_SOURCE_RIGHT_CLICK_REFACTOR
  • COMMAND_REQUEST_SOURCE_FUNCTION_CODE_LENS
  • COMMAND_REQUEST_SOURCE_FOLLOWUP
  • COMMAND_REQUEST_SOURCE_CLASS_CODE_LENS
  • COMMAND_REQUEST_SOURCE_PLAN
  • COMMAND_REQUEST_SOURCE_SELECTION_HINT_CODE_LENS

Provider Sources

  • PROVIDER_SOURCE_COMMAND_GENERATE - Generation mode
  • PROVIDER_SOURCE_COMMAND_EDIT - Edit mode

PCW Data

Percent Code Written data with separate tracking for autocomplete and command contributions.
Field NameDescriptionValid Aggregations
percent_code_writtenCalculated as windsurf_bytes / (windsurf_bytes + user_bytes)UNSPECIFIED
windsurf_bytesTotal Windsurf-generated bytesUNSPECIFIED
user_bytesTotal user-written bytesUNSPECIFIED
total_byteswindsurf_bytes + user_bytesUNSPECIFIED
windsurf_bytes_by_autocompleteWindsurf bytes from autocompleteUNSPECIFIED
windsurf_bytes_by_commandWindsurf bytes from commandUNSPECIFIED

PCW Filters

Field NameDescriptionExamples
api_keyHash of user API key
emailUser email addressuser@example.com
languageProgramming languageKOTLIN, GO, JAVA
ideIDE being usedjetbrains, vscode
versionWindsurf version1.28.0, 130.0
For date filtering in PCW queries, use start_timestamp and end_timestamp in the main request body.

Example Requests

User Data Example

curl -X POST --header "Content-Type: application/json" \
--data '{
  "service_key": "your_service_key_here",
  "query_requests": [
    {
      "data_source": "QUERY_DATA_SOURCE_USER_DATA",
      "selections": [
        {
          "field": "num_acceptances",
          "name": "total_acceptances",
          "aggregation_function": "QUERY_AGGREGATION_SUM"
        },
        {
          "field": "num_lines_accepted",
          "name": "total_lines",
          "aggregation_function": "QUERY_AGGREGATION_SUM"
        }
      ],
      "filters": [
        {
          "name": "hour",
          "filter": "QUERY_FILTER_GE",
          "value": "2024-01-01"
        },
        {
          "name": "hour",
          "filter": "QUERY_FILTER_LE",
          "value": "2024-02-01"
        }
      ]
    }
  ]
}' \
https://server.codeium.com/api/v1/Analytics

Chat Data Example

curl -X POST --header "Content-Type: application/json" \
--data '{
  "service_key": "your_service_key_here",
  "query_requests": [
    {
      "data_source": "QUERY_DATA_SOURCE_CHAT_DATA",
      "selections": [
        {
          "field": "chat_loc_used",
          "name": "lines_used",
          "aggregation_function": "QUERY_AGGREGATION_SUM"
        }
      ],
      "filters": [
        {
          "name": "latest_intent_type",
          "filter": "QUERY_FILTER_EQUAL",
          "value": "CHAT_INTENT_FUNCTION_DOCSTRING"
        }
      ],
      "aggregations": [
        {
          "field": "ide",
          "name": "ide_type"
        }
      ]
    }
  ]
}' \
https://server.codeium.com/api/v1/Analytics

Command Data Example

curl -X POST --header "Content-Type: application/json" \
--data '{
  "service_key": "your_service_key_here",
  "query_requests": [
    {
      "data_source": "QUERY_DATA_SOURCE_COMMAND_DATA",
      "selections": [
        {
          "field": "lines_added",
          "name": "total_lines_added",
          "aggregation_function": "QUERY_AGGREGATION_SUM"
        },
        {
          "field": "lines_removed",
          "name": "total_lines_removed",
          "aggregation_function": "QUERY_AGGREGATION_SUM"
        }
      ],
      "filters": [
        {
          "name": "provider_source",
          "filter": "QUERY_FILTER_EQUAL",
          "value": "PROVIDER_SOURCE_COMMAND_EDIT"
        },
        {
          "name": "accepted",
          "filter": "QUERY_FILTER_EQUAL",
          "value": "true"
        }
      ],
      "aggregations": [
        {
          "field": "language",
          "name": "programming_language"
        }
      ]
    }
  ]
}' \
https://server.codeium.com/api/v1/Analytics

PCW Data Example

curl -X POST --header "Content-Type: application/json" \
--data '{
  "service_key": "your_service_key_here",
  "start_timestamp": "2024-01-01T00:00:00Z",
  "end_timestamp": "2024-12-22T00:00:00Z",
  "query_requests": [
    {
      "data_source": "QUERY_DATA_SOURCE_PCW_DATA",
      "selections": [
        {
          "field": "percent_code_written",
          "name": "pcw"
        },
        {
          "field": "windsurf_bytes",
          "name": "ai_bytes"
        },
        {
          "field": "total_bytes",
          "name": "total"
        },
        {
          "field": "windsurf_bytes_by_autocomplete",
          "name": "autocomplete_bytes"
        },
        {
          "field": "windsurf_bytes_by_command",
          "name": "command_bytes"
        }
      ],
      "filters": [
        {
          "filter": "QUERY_FILTER_EQUAL",
          "name": "language",
          "value": "GO"
        }
      ]
    }
  ]
}' \
https://server.codeium.com/api/v1/Analytics

Response

queryResults
array
Array of query results, one for each query request
responseItems
array
Array of result items
item
object
Object containing the selected fields and their values

Example Responses

User Data Response

{
  "queryResults": [
    {
      "responseItems": [
        {
          "item": {
            "total_acceptances": "125",
            "total_lines": "863"
          }
        }
      ]
    }
  ]
}

Chat Data Response

{
  "queryResults": [
    {
      "responseItems": [
        {
          "item": {
            "lines_used": "74",
            "ide_type": "jetbrains"
          }
        },
        {
          "item": {
            "lines_used": "41",
            "ide_type": "vscode"
          }
        }
      ]
    }
  ]
}

Command Data Response

{
  "queryResults": [
    {
      "responseItems": [
        {
          "item": {
            "programming_language": "PYTHON",
            "total_lines_added": "21",
            "total_lines_removed": "5"
          }
        },
        {
          "item": {
            "programming_language": "GO",
            "total_lines_added": "31",
            "total_lines_removed": "27"
          }
        }
      ]
    }
  ]
}

PCW Data Response

{
  "queryResults": [
    {
      "responseItems": [
        {
          "item": {
            "ai_bytes": "6018",
            "autocomplete_bytes": "4593",
            "command_bytes": "1425",
            "pcw": "0.61",
            "total": "9900"
          }
        }
      ]
    }
  ]
}

Important Notes

  • PCW (Percent Code Written) has high variance within single days or users - aggregate over weeks for better insights
  • All selection fields must either have aggregation functions or none should (cannot mix)
  • Fields with “distinct_*” pattern cannot be used in aggregations
  • Field aliases must be unique across all selections and aggregations
  • If no aggregation function is specified, it defaults to UNSPECIFIED