> ## 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.

# Récupérer les utilisateurs actifs

> Interrogez le nombre d'utilisateurs actifs distincts de votre Team, avec une granularité temporelle facultative et un regroupement par utilisateur.

<Note>
  Il s'agit d'un **endpoint v2** qui utilise l'authentification par jeton Bearer et des paramètres de requête, contrairement à l'Analytics API v1, qui utilise des clés de service dans le corps de la requête. Voir [Authentification](#authentication) ci-dessous.
</Note>

<Warning>
  Cet endpoint n'est **pas** conçu pour le suivi de l'utilisation en temps réel. Les données sont agrégées à l'heure et la
  limite de débit est faible (10 requêtes par heure et par Team). Utilisez-le pour les rapports périodiques et les exports en masse.
</Warning>

<div id="authentication">
  ## Authentification
</div>

Cet endpoint utilise l’authentification par **jeton Bearer**. Incluez votre clé de service dans l’en-tête `Authorization` :

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

La clé de service doit disposer de l’autorisation **Analytics Read**. Créez-en une dans les [Team Settings](https://windsurf.com/team/settings), sous "Service Keys".

<div id="what-counts-as-an-active-user">
  ## Ce qui est considéré comme un utilisateur actif
</div>

Un utilisateur est considéré comme **actif** pour un intervalle de temps donné s’il y a un événement de facturation associé. Le
champ `active_users` indique le nombre d’utilisateurs distincts.

<Note>
  Le nombre d’utilisateurs actifs inclut l’utilisation provenant de **Devin CLI et Devin Desktop**. Un utilisateur qui est
  actif dans l’un ou l’autre (ou les deux) est comptabilisé, et il n’est compté qu’une seule fois par intervalle de temps.
</Note>

<div id="grouping-and-granularity">
  ## Regroupement et granularité
</div>

Utilisez `granularity` et `group_by` pour contrôler la structure des données renvoyées :

* **Aucune granularité ni regroupement** — renvoie une seule ligne avec le nombre total d’utilisateurs actifs sur toute la plage de dates
* **`granularity=daily`** — chaque ligne inclut un `timestamp` au format `YYYY-MM-DD` (utilisateurs actifs quotidiens)
* **`granularity=monthly`** — chaque ligne inclut un `timestamp` au format `YYYY-MM` (utilisateurs actifs mensuels)
* **`group_by=user`** — renvoie une ligne par utilisateur actif avec un `user_id` ; la valeur de `active_users` est `1` pour chaque ligne

<Note>
  Contrairement à [Get Consumption](/fr/desktop/accounts/api-reference/get-consumption), l’endpoint des utilisateurs actifs
  n’accepte que `user` pour `group_by`. Les autres dimensions (`model_uid`, `ide`) ne sont pas valides ici.
</Note>

<div id="pagination">
  ## Pagination
</div>

Les résultats sont paginés, avec une taille de page par défaut de 1 000 lignes (maximum : 10 000). Lorsque d’autres résultats sont disponibles,
la réponse inclut un `next_page_cursor` dans l’objet `pagination`. Transmettez-le comme paramètre de requête `page_cursor`
pour récupérer la page suivante.

Les curseurs de page expirent après 24 heures. Une requête de page suivante n’est pas comptabilisée comme une nouvelle requête au regard de votre limite de débit.

<div id="caching">
  ## Mise en cache
</div>

Les réponses comportent un en-tête `ETag`. Pour éviter des transferts de données inutiles, incluez l’en-tête `If-None-Match`
avec la valeur `ETag` précédente — le serveur renverra `304 Not Modified` si les données n’ont pas changé.

<div id="rate-limits">
  ## Limites de débit
</div>

Cet endpoint est soumis à une limite de **10 requêtes par heure** par Team. Si vous dépassez cette limite, le
serveur renvoie `429 Too Many Requests` avec un `Retry-After` en-tête.

La pagination d’une requête précédente (en suivant un `next_page_cursor`) n’est **pas** décomptée de cette limite —
seule la requête initiale de chaque rapport compte. Cette faible limite s’explique par le fait que cet endpoint est destiné à
des rapports périodiques, et non au suivi de l’utilisation en temps réel.


## OpenAPI

````yaml fr/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: >
    L’Analytics API v2 fournit des analyses de consommation de crédits et d’ACU
    pour les Teams Enterprise.

    Les données proviennent d’événements de Billing agrégés par heure et
    prennent en charge un filtrage flexible, le regroupement

    et la pagination par curseur.
servers:
  - url: https://server.codeium.com
security:
  - bearerAuth: []
paths:
  /api/v2alpha/analytics/active-users:
    get:
      summary: Récupérer l’analyse des utilisateurs actifs
      description: "Interrogez le nombre de users actifs distincts pour la Team authentifiée. Un user est comptabilisé comme actif pour un intervalle temporel s’il comporte au moins un événement de Billing. Les résultats proviennent d’événements de Billing agrégés par heure et peuvent être filtrés par plage de dates, produit, modèle et groupe.\n\nUtilisez `granularity` pour ventiler le décompte par jour ou par mois, et `group_by=user` pour renvoyer une ligne par user (la valeur `active_users` de chaque ligne sera `1`).\n\nLes réponses sont mises en cache pendant 1 heure. Utilisez `If-None-Match` avec un `ETag` précédemment renvoyé pour recevoir une réponse `304 Not Modified` lorsque les données n’ont pas changé.\n\nCes endpoints sont conçus pour le reporting périodique et l’export en masse. Ils ne sont **pas** destinés au suivi de l’utilisation en temps réel\_: les données sont agrégées par heure et la limite de débit est faible (10 requêtes par heure et par Team).\n"
      operationId: getActiveUsers
      parameters:
        - name: start_date
          in: query
          required: true
          schema:
            type: string
            format: date
          description: Début de la plage de dates (inclus) au format `YYYY-MM-DD`.
          example: '2026-01-01T00:00:00.000Z'
        - name: end_date
          in: query
          required: true
          schema:
            type: string
            format: date
          description: >-
            Fin de la plage de dates (incluse) au format `YYYY-MM-DD`. La plage
            ne doit pas dépasser 90 jours.
          example: '2026-01-31T00:00:00.000Z'
        - name: product
          in: query
          required: true
          schema:
            type: string
            enum:
              - agent
          description: Produit pour lequel interroger les users actifs.
          example: agent
        - name: granularity
          in: query
          required: false
          schema:
            type: string
            enum:
              - daily
              - monthly
          description: >
            Granularité temporelle pour regrouper les résultats. Lorsqu’elle est
            spécifiée, chaque ligne inclut un champ `timestamp`.

            Si elle est omise, le nombre de users actifs est agrégé sur
            l’ensemble de la plage de dates.
        - name: group_by
          in: query
          required: false
          schema:
            type: string
            enum:
              - user
          description: >
            Dimension selon laquelle regrouper les résultats. L'endpoint des
            utilisateurs actifs ne prend en charge que `user`, ce qui renvoie

            une ligne par utilisateur actif (avec `active_users` = `1` pour
            chacun).
          example: user
        - name: models
          in: query
          required: false
          schema:
            type: string
          description: >-
            Liste d'UID de modèle, séparés par des virgules, à utiliser pour
            filtrer les résultats.
          example: claude-4-sonnet,gpt-4.1
        - name: group_id
          in: query
          required: false
          schema:
            type: string
          description: >-
            Filtrer les résultats pour n'inclure que les utilisateurs d'un
            groupe spécifique. La clé de service doit avoir accès à ce groupe.
        - name: user_id
          in: query
          required: false
          schema:
            type: string
          description: >-
            Filtrer les résultats pour un utilisateur spécifique (UID
            d'authentification).
        - name: page_size
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 10000
            default: 1000
          description: Nombre maximal de lignes à renvoyer par page.
        - name: page_cursor
          in: query
          required: false
          schema:
            type: string
          description: >-
            Curseur opaque provenant du champ `pagination.next_page_cursor`
            d'une réponse précédente, à utiliser pour récupérer la page
            suivante.
        - name: If-None-Match
          in: header
          required: false
          schema:
            type: string
          description: >-
            Valeur ETag provenant d'une réponse précédente. Si les données n'ont
            pas changé, le server renvoie `304 Not Modified`.
      responses:
        '200':
          description: Données sur les utilisateurs actifs renvoyées avec succès.
          headers:
            ETag:
              schema:
                type: string
              description: >-
                Balise d'entité utilisée pour la validation du cache.
                Transmettez-la sous la forme `If-None-Match` dans les requêtes
                suivantes.
            Cache-Control:
              schema:
                type: string
              description: "Directive de cache (p.\_ex. `private, max-age=3600`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ActiveUsersResponse'
              examples:
                aggregate:
                  summary: >-
                    Nombre total d’utilisateurs actifs sur la période
                    sélectionnée
                  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: Utilisateurs actifs quotidiens
                  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: Regroupé par utilisateur
                  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: >-
            Les données n'ont pas changé depuis l'ETag fourni dans
            `If-None-Match`.
        '400':
          description: Paramètres de requête non valides.
          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: Échec de l'authentification ou autorisations insuffisantes.
          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: >-
            Le curseur de page fourni n'appartient pas à la Team authentifiée ni
            au groupe demandé.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                cursor_team_mismatch:
                  value:
                    error: page cursor does not belong to this team
        '405':
          description: Méthode HTTP non autorisée (seul `GET` est pris en charge).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: >-
            Limite de débit dépassée (10 requêtes par heure et par Team). La
            pagination d'une requête précédente n'est pas comptabilisée dans
            cette limite.
          headers:
            Retry-After:
              schema:
                type: string
              description: Délai d'attente suggéré avant une nouvelle tentative.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                rate_limited:
                  value:
                    error: rate limit exceeded
        '503':
          description: "Le service d'analyse n'est pas disponible (p.\_ex. dans les déploiements self-hosted)."
          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: Tableau de lignes de données sur les utilisateurs actifs.
        pagination:
          type: object
          properties:
            next_page_cursor:
              type:
                - string
                - 'null'
              description: "Curseur opaque permettant de récupérer la page de résultats suivante. Transmettez cette valeur comme paramètre de requête `page_cursor`\ndans une requête suivante. `null` lorsqu’il n’y a plus de pages.\nLes curseurs de page expirent après 24\_heures.\n"
        metadata:
          type: object
          properties:
            data_freshness:
              type: string
              format: date-time
              description: >-
                Horodatage indiquant quand les données sous-jacentes ont été
                actualisées pour la dernière fois (tronqué à l’heure).
            query_time_ms:
              type: integer
              format: int64
              description: Temps d’exécution de la requête côté serveur, en millisecondes.
            team_id:
              type: string
              description: >-
                L’ID de la Team déterminé à partir de la clé de service
                authentifiée.
            group_id:
              type: string
              description: >-
                L’ID du groupe auquel les résultats se limitaient. Présent
                uniquement lorsque `group_id` a été fourni.
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: string
          description: Message d’erreur compréhensible par un humain.
    ActiveUsersRow:
      type: object
      required:
        - active_users
      properties:
        timestamp:
          type: string
          description: "Tranche temporelle de la ligne. Le format dépend de `granularity`\_: `YYYY-MM-DD` pour le jour, `YYYY-MM` pour le mois.\nPrésent uniquement lorsque `granularity` est spécifié.\n"
          examples:
            - '2026-05-01T00:00:00.000Z'
            - 2026-05
        user_id:
          type: string
          description: >-
            Identifiant de l’utilisateur (UID d’authentification). Présent
            uniquement lorsque `group_by` inclut `user`.
        active_users:
          type: integer
          format: int64
          description: >
            Nombre d’utilisateurs actifs distincts dans la ligne. Un utilisateur
            est compté comme actif pour une tranche temporelle s’il

            y a au moins un événement de Billing. Lorsqu’il est regroupé par
            `user`, ce nombre vaut toujours `1`.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >
        Une clé de service disposant de l’autorisation **Analytics Read**,
        transmise comme jeton Bearer dans l’en-tête `Authorization`.


        Créez une clé de service dans les paramètres de votre Team, à l’adresse
        [team settings](https://windsurf.com/team/settings), dans la section
        "Service Keys".

````