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

# Python SDK

> Query analytics and manage groups and ACU limits from the command line with the Python SDK.

<Info>
  This documentation is for the federal deployments of Devin. [Back to Devin Docs](/get-started/devin-intro)
</Info>

The Python SDK (`windsurf_analytics.py`) is a command-line client for the endpoints in the [federal API](/federal/api/overview): usage reports, [ACU consumption](/federal/api/acu-consumption), [group management](/federal/api/group-management), and [user ACU caps](/federal/api/acu-caps). Contact your Cognition representative to obtain the script for your deployment.

## Requirements

* Python 3
* The `requests` library: `pip install requests`

## Authentication

Every command takes these shared flags:

| Flag            | Description                                                                                          |
| --------------- | ---------------------------------------------------------------------------------------------------- |
| `--service-key` | Service key for authentication. Can also be set via the `WINDSURF_SERVICE_KEY` environment variable. |
| `--api-url`     | Base URL of your deployment's API server (`https://<your-server>`). HTTPS is required.               |

The service key's role must carry the permission required by each command — see the [permission table](/federal/api/overview#required-permissions). All analytics commands also require a team tier with analytics API access.

## Commands

| Command                | Endpoint                                   | Required permission |
| ---------------------- | ------------------------------------------ | ------------------- |
| `usage` (default)      | `/UserPageAnalytics` + `/CascadeAnalytics` | Teams Read-Only     |
| `acu-consumption`      | `/Analytics`                               | Analytics Read      |
| `list-groups`          | `/ListGroups`                              | Teams Read-Only     |
| `get-group`            | `/GetGroup`                                | Teams Read-Only     |
| `create-group`         | `/CreateGroup`                             | Teams Update        |
| `update-group`         | `/UpdateGroup`                             | Teams Update        |
| `delete-group`         | `/DeleteGroup`                             | Teams Update        |
| `list-group-members`   | `/ListGroupMembers`                        | Teams Read-Only     |
| `add-group-members`    | `/AddGroupMembers`                         | Teams Update        |
| `remove-group-members` | `/RemoveGroupMembers`                      | Teams Update        |
| `get-user-acu-cap`     | `/GetUserAcuCap`                           | Teams Read-Only     |
| `update-user-acu-cap`  | `/UpdateUserAcuCap`                        | Teams Update        |

Running the script without a command (the original invocation) runs the `usage` report.

## Output and errors

All commands print JSON to stdout. Paginated results (ACU consumption user rows, `list-groups`, `list-group-members`) are automatically followed to the last page and merged into a single response. API errors are printed to stderr as `code: message` and the script exits with status `1`.

## Examples

### Per-user usage report

```bash theme={null}
python windsurf_analytics.py \
    --service-key YOUR_SERVICE_KEY \
    --api-url https://your-server.com \
    --start 2025-01-01T00:00:00Z \
    --end 2025-03-31T23:59:59Z
```

### ACU consumption

```bash theme={null}
# Team ACU total plus per-user rows for the current billing cycle
python windsurf_analytics.py acu-consumption \
    --api-url https://your-server.com \
    --current-cycle --include-team-total --team-user-rows

# Historical per-group breakdown (window must span at most 90 days),
# with per-user rows for one group
python windsurf_analytics.py acu-consumption \
    --api-url https://your-server.com \
    --start 2025-01-01T00:00:00Z --end 2025-03-31T23:59:59Z \
    --group-id GROUP_A_ID --group-user-rows GROUP_A_ID
```

`acu-consumption` flags: `--current-cycle` or `--start`/`--end` select the period; `--include-team-total`, repeatable `--group-id` (max 100), and mutually exclusive `--team-user-rows` / `--group-user-rows GROUP_ID` select the data; `--page-size` tunes the per-request page size (all pages are fetched regardless). At least one data selection flag is required. A group-scoped key can select only its assigned group and cannot request team totals or team user rows.

### Group management

```bash theme={null}
# List groups and read one group
python windsurf_analytics.py list-groups --api-url https://your-server.com
python windsurf_analytics.py get-group --api-url https://your-server.com \
    --group-id GROUP_ID

# Create a group, configure its models and ACU cap
python windsurf_analytics.py create-group --api-url https://your-server.com \
    --name Engineering
python windsurf_analytics.py update-group --api-url https://your-server.com \
    --group-id GROUP_ID \
    --cascade-models MODEL_UID_1,MODEL_UID_2 \
    --set-cycle-acu-limit 50

# Clear a group's model restriction or ACU cap. The service API requires a
# positive value when setting a group cap; clearing is a separate operation.
python windsurf_analytics.py update-group --api-url https://your-server.com \
    --group-id GROUP_ID --clear-cascade-models --clear-cycle-acu-limit

# Manage membership (comma-separated emails, max 1000)
python windsurf_analytics.py add-group-members --api-url https://your-server.com \
    --group-id GROUP_ID --emails dev@agency.gov,lead@agency.gov
python windsurf_analytics.py remove-group-members --api-url https://your-server.com \
    --group-id GROUP_ID --emails dev@agency.gov

# Delete a group (idempotent)
python windsurf_analytics.py delete-group --api-url https://your-server.com \
    --group-id GROUP_ID
```

### User ACU caps

```bash theme={null}
# Read a user's configured and effective cap (select by --email or --user-id)
python windsurf_analytics.py get-user-acu-cap --api-url https://your-server.com \
    --email dev@agency.gov

# Set a cap (0 blocks the user) or clear the override
python windsurf_analytics.py update-user-acu-cap --api-url https://your-server.com \
    --email dev@agency.gov --set-cycle-acu-limit 25
python windsurf_analytics.py update-user-acu-cap --api-url https://your-server.com \
    --email dev@agency.gov --clear-cycle-acu-limit
```
