> ## Documentation Index
> Fetch the complete documentation index at: https://docs.devin.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# 获取活跃用户数

> 查询你团队的独立活跃用户数，并可选择时间粒度和按用户分组。

<Note>
  这是一个**v2 端点**，使用 Bearer 令牌进行身份验证和查询参数；不同于 v1 分析 API，后者在请求体中使用服务密钥。请参阅下方的 [身份验证](#authentication)。
</Note>

<Warning>
  此端点**不**适用于实时用量监控。数据按小时聚合，且
  速率限制较低 (每个团队每小时 10 个请求) 。请将其用于定期报告和批量导出。
</Warning>

<div id="authentication">
  ## 身份验证
</div>

此端点使用 **Bearer 令牌** 进行身份验证。请在 `Authorization` 标头中包含你的服务密钥：

```
Authorization: Bearer <your_service_key>
```

服务密钥必须具备 **Analytics Read** 权限。可在[团队设置](https://windsurf.com/team/settings)中的 "Service Keys" 下创建一个。

<div id="what-counts-as-an-active-user">
  ## 什么情况下会计为活跃用户
</div>

如果某个用户在给定时间段内有任何计费事件，则会被计为**活跃**。`active_users` 字段表示不同用户的数量。

<Note>
  活跃用户数包含 **Devin CLI 和 Devin Desktop 两者** 的用量。用户只要在其中任一方
  (或两者) 有用量，就会被计入，并且每个时间段只会计一次。
</Note>

<div id="grouping-and-granularity">
  ## 分组与粒度
</div>

使用 `granularity` 和 `group_by` 控制返回数据的结构：

* **不设置粒度或分组** — 返回单行数据，其中包含整个日期范围内的活跃用户总数
* **`granularity=daily`** — 每行都包含一个 `YYYY-MM-DD` 格式的 `timestamp` (日活跃用户)
* **`granularity=monthly`** — 每行都包含一个 `YYYY-MM` 格式的 `timestamp` (月活跃用户)
* **`group_by=user`** — 每个活跃用户返回一行，并包含 `user_id`；每行的 `active_users` 都为 `1`

<Note>
  与 [获取用量](/zh/desktop/accounts/api-reference/get-consumption) 不同，活跃用户端点的
  `group_by` 仅支持 `user`。其他维度 (`model_uid`、`ide`) 在此处无效。
</Note>

<div id="pagination">
  ## 分页
</div>

结果将按分页返回，默认页面大小为 1,000 行 (最大 10,000 行) 。当有更多结果时，
响应会在 `pagination` 对象中包含一个 `next_page_cursor`。将其作为 `page_cursor` 查询
参数传入，以获取下一页。

页面游标会在 24 小时后过期。后续的分页请求不会作为新的查询计入你的速率限制。

<div id="caching">
  ## 缓存
</div>

响应中包含一个 `ETag` 标头。为避免重复传输数据，请在请求中附带之前的 `ETag` 值作为 `If-None-Match` 标头；如果数据未发生变化，服务器将返回 `304 Not Modified`。

<div id="rate-limits">
  ## 速率限制
</div>

此端点按团队限制为**每小时 10 次请求**。如果你超出此限制，
服务器会返回 `429 Too Many Requests`，并附带 `Retry-After` 标头。

对先前查询结果进行分页 (沿用 `next_page_cursor`) **不会**计入此限制——
只有每份报告的初始查询才会计入。较低的限制说明，此端点用于
定期报告，而非实时用量监控。


## OpenAPI

````yaml zh/desktop/accounts/api-reference/analytics-v2-openapi.yaml GET /api/v2alpha/analytics/active-users
openapi: 3.1.0
info:
  title: Devin Desktop Analytics API v2
  version: 2.0.0
  description: |
    分析 API v2 为企业团队提供积分和 ACU 用量分析。
    数据来自按小时聚合的计费事件，并支持灵活筛选、分组和基于游标的分页。
servers:
  - url: https://server.codeium.com
security:
  - bearerAuth: []
paths:
  /api/v2alpha/analytics/active-users:
    get:
      summary: 获取活跃用户分析
      description: >
        查询已通过身份验证的团队中不同活跃用户的数量。如果用户在某个时间桶内有任何计费事件，则该用户会被计为该时间桶中的活跃用户。结果来自按小时聚合的计费事件，可按日期范围、产品、模型和组进行筛选。


        使用 `granularity` 可按天或按月拆分计数，使用 `group_by=user` 可为每个用户返回一行（每一行的
        `active_users` 都将为 `1`）。


        响应会缓存 1 小时。将之前返回的 `ETag` 与 `If-None-Match` 搭配使用，即可在数据未发生变化时收到 `304 Not
        Modified`。


        这些端点适用于定期报告和批量导出。它们**不**适用于实时用量监控：数据按小时聚合，且速率限制较低（每个团队每小时 10 个请求）。
      operationId: getActiveUsers
      parameters:
        - name: start_date
          in: query
          required: true
          schema:
            type: string
            format: date
          description: 日期范围的开始日期（含），格式为 `YYYY-MM-DD`。
          example: '2026-01-01T00:00:00.000Z'
        - name: end_date
          in: query
          required: true
          schema:
            type: string
            format: date
          description: 日期范围的结束日期（含），格式为 `YYYY-MM-DD`。范围不得超过 90 天。
          example: '2026-01-31T00:00:00.000Z'
        - name: product
          in: query
          required: true
          schema:
            type: string
            enum:
              - agent
          description: 要查询活跃用户数的产品。
          example: agent
        - name: granularity
          in: query
          required: false
          schema:
            type: string
            enum:
              - daily
              - monthly
          description: |
            用于对结果分组的时间粒度。指定后，每一行都包含 `timestamp` 字段。
            如果省略，活跃用户数会在整个日期范围内聚合。
        - name: group_by
          in: query
          required: false
          schema:
            type: string
            enum:
              - user
          description: |
            用于对结果分组的维度。活跃用户端点仅支持 `user`，这会为每个活跃用户返回一行
            （每行的 `active_users` = `1`）。
          example: user
        - name: models
          in: query
          required: false
          schema:
            type: string
          description: 用于筛选结果的模型 UID 逗号分隔列表。
          example: claude-4-sonnet,gpt-4.1
        - name: group_id
          in: query
          required: false
          schema:
            type: string
          description: 将结果筛选为特定组中的用户。服务密钥必须具有该组的访问权限。
        - name: user_id
          in: query
          required: false
          schema:
            type: string
          description: 将结果筛选为特定用户（auth UID）。
        - name: page_size
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 10000
            default: 1000
          description: 每页返回的最大行数。
        - name: page_cursor
          in: query
          required: false
          schema:
            type: string
          description: 来自上一个响应中 `pagination.next_page_cursor` 的不透明游标，用于获取下一页。
        - name: If-None-Match
          in: header
          required: false
          schema:
            type: string
          description: 来自上一个响应的 ETag 值。如果数据未发生变化，服务器将返回 `304 Not Modified`。
      responses:
        '200':
          description: 活跃用户数据已成功返回。
          headers:
            ETag:
              schema:
                type: string
              description: 用于缓存验证的实体标签。请在后续请求中通过 `If-None-Match` 传递此值。
            Cache-Control:
              schema:
                type: string
              description: 缓存指令（例如 `private, max-age=3600`）。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ActiveUsersResponse'
              examples:
                aggregate:
                  summary: 所选日期范围内的活跃用户总数
                  value:
                    data:
                      - active_users: 142
                    pagination:
                      next_page_cursor: null
                    metadata:
                      data_freshness: '2026-01-16T03:00:00.000Z'
                      query_time_ms: 612
                      team_id: team_abc123
                daily:
                  summary: 每日活跃用户
                  value:
                    data:
                      - timestamp: '2026-01-15T00:00:00.000Z'
                        active_users: 138
                      - timestamp: '2026-01-16T00:00:00.000Z'
                        active_users: 145
                    pagination:
                      next_page_cursor: null
                    metadata:
                      data_freshness: '2026-01-16T03:00:00.000Z'
                      query_time_ms: 734
                      team_id: team_abc123
                by_user:
                  summary: 按用户分组
                  value:
                    data:
                      - user_id: user_abc123
                        active_users: 1
                      - user_id: user_def456
                        active_users: 1
                    pagination:
                      next_page_cursor: null
                    metadata:
                      data_freshness: '2026-01-16T03:00:00.000Z'
                      query_time_ms: 845
                      team_id: team_abc123
        '304':
          description: 自 `If-None-Match` 中提供的 ETag 以来，数据未发生变化。
        '400':
          description: 请求参数无效。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                missing_param:
                  value:
                    error: start_date is required
                bad_group_by:
                  value:
                    error: 'unsupported group_by dimension for active-users: model_uid'
                bad_product:
                  value:
                    error: 'unsupported product: foo (supported: agent)'
        '401':
          description: 身份验证失败或权限不足。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                missing_auth:
                  value:
                    error: missing Authorization header
                invalid_key:
                  value:
                    error: invalid service key
                insufficient_permissions:
                  value:
                    error: insufficient permissions
        '403':
          description: 提供的页面游标不属于已通过身份验证的团队或请求的组。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                cursor_team_mismatch:
                  value:
                    error: page cursor does not belong to this team
        '405':
          description: 不允许使用该 HTTP 方法（仅支持 `GET`）。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: 已超出速率限制（每个团队每小时 10 个请求）。对较早查询进行分页不计入此限制。
          headers:
            Retry-After:
              schema:
                type: string
              description: 重试前建议等待的时间。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                rate_limited:
                  value:
                    error: rate limit exceeded
        '503':
          description: 分析服务不可用（例如在自托管部署中）。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - bearerAuth: []
components:
  schemas:
    ActiveUsersResponse:
      type: object
      required:
        - data
        - pagination
        - metadata
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/ActiveUsersRow'
          description: 活跃用户数据行数组。
        pagination:
          type: object
          properties:
            next_page_cursor:
              type:
                - string
                - 'null'
              description: |
                用于获取下一页结果的不透明游标。在后续请求中，将此值作为 `page_cursor`
                查询参数传递。如果没有更多页面，则为 `null`。
                页面游标会在 24 小时后过期。
        metadata:
          type: object
          properties:
            data_freshness:
              type: string
              format: date-time
              description: 表示底层数据上次刷新时间的时间戳（截断到小时）。
            query_time_ms:
              type: integer
              format: int64
              description: 服务器端查询执行时间（毫秒）。
            team_id:
              type: string
              description: 从已通过身份验证的服务密钥解析出的团队 ID。
            group_id:
              type: string
              description: 结果所限定的组 ID。仅在提供了 `group_id` 时显示。
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: string
          description: 便于人工阅读的错误消息。
    ActiveUsersRow:
      type: object
      required:
        - active_users
      properties:
        timestamp:
          type: string
          description: |
            该行的时间桶。格式取决于 `granularity`：按天为 `YYYY-MM-DD`，按月为 `YYYY-MM`。
            仅在指定了 `granularity` 时出现。
          examples:
            - '2026-05-01T00:00:00.000Z'
            - 2026-05
        user_id:
          type: string
          description: 用户标识符（auth UID）。仅在 `group_by` 包含 `user` 时出现。
        active_users:
          type: integer
          format: int64
          description: >
            该行中不同活跃用户的数量。如果用户在某个时间桶内有任意计费事件，则会被计为该时间桶内的活跃用户。按 `user` 分组时，该值始终为
            `1`。
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >
        需要一个具有 **Analytics Read** 权限的服务密钥，并通过 `Authorization` 标头以 Bearer
        令牌的形式传递。


        你可以在[团队设置](https://windsurf.com/team/settings)中的“Service Keys”部分创建服务密钥。

````