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

# Users API — Identify, List, and Delete User Profiles

> Use the Users API to create and update user profiles with traits, list your user base, retrieve individual profiles, and delete users for GDPR compliance.

The Users API manages user profiles and their associated traits inside Cano Analytics. Use it to identify users when they sign up or log in, enrich profiles with traits like plan or email, and look up or delete user records programmatically. All requests require a valid API key sent as a Bearer token.

***

## POST /v1/identify — Identify a User

Create or update a user profile and attach traits to it. If the `user_id` already exists, Cano Analytics merges the new traits with the existing profile. This endpoint requires the **write** scope.

### Body parameters

<ParamField body="user_id" type="string" required>
  Your application's unique identifier for this user. Cano Analytics uses this as the canonical user key.
</ParamField>

<ParamField body="traits" type="object">
  A key-value object of user attributes. Common fields include `name`, `email`, `plan`, `company`, and `created_at`, but you can include any custom trait.
</ParamField>

<ParamField body="timestamp" type="string">
  ISO 8601 timestamp indicating when the identification occurred. Defaults to server time if omitted.
</ParamField>

### Request example

```json POST /v1/identify theme={null}
{
  "user_id": "usr_4f8a1c",
  "traits": {
    "name": "Jordan Lee",
    "email": "jordan@example.com",
    "plan": "pro",
    "company": "Acme Corp",
    "created_at": "2024-01-10T08:00:00Z"
  },
  "timestamp": "2024-06-15T14:00:00Z"
}
```

### Response — 200 OK

```json 200 OK theme={null}
{
  "id": "usr_4f8a1c",
  "status": "identified",
  "received_at": "2024-06-15T14:00:01.221Z"
}
```

***

## GET /v1/users — List Users

Retrieve a paginated list of all user profiles in your workspace. This endpoint requires the **read** scope.

### Query parameters

<ParamField query="limit" type="integer">
  Number of users to return per page. Defaults to `100`. Maximum is `1000`.
</ParamField>

<ParamField query="cursor" type="string">
  Opaque pagination cursor from the previous response's `next_cursor` field.
</ParamField>

<ParamField query="trait[{key}]" type="string">
  Filter users by a specific trait value. For example, `?trait[plan]=pro` returns only users whose `plan` trait equals `"pro"`. You can combine multiple trait filters in one request.
</ParamField>

### Request example

```bash cURL theme={null}
curl -G https://api.canoanalytics.io/v1/users \
  -H "Authorization: Bearer YOUR_API_KEY" \
  --data-urlencode "trait[plan]=pro" \
  --data-urlencode "limit=50"
```

### Response — 200 OK

```json 200 OK theme={null}
{
  "data": [
    {
      "id": "usr_4f8a1c",
      "traits": {
        "name": "Jordan Lee",
        "email": "jordan@example.com",
        "plan": "pro"
      },
      "created_at": "2024-01-10T08:00:00Z",
      "last_seen_at": "2024-06-15T14:32:00Z",
      "event_count": 284
    }
  ],
  "next_cursor": "cur_eyJ1c2VyIjoyfQ",
  "has_more": false
}
```

<ResponseField name="data" type="array">
  An array of user profile objects matching your query.
</ResponseField>

<ResponseField name="next_cursor" type="string">
  Opaque cursor for the next page. `null` when no more pages exist.
</ResponseField>

<ResponseField name="has_more" type="boolean">
  `true` if additional pages of results are available.
</ResponseField>

***

## GET /v1/users/{user_id} — Get a User

Retrieve the full profile for a single user by their ID. This endpoint requires the **read** scope.

### Path parameters

<ParamField path="user_id" type="string" required>
  The unique identifier of the user to retrieve.
</ParamField>

### Response fields

<ResponseField name="id" type="string">
  The user's unique identifier.
</ResponseField>

<ResponseField name="traits" type="object">
  All traits associated with this user, merged from every `identify` call.
</ResponseField>

<ResponseField name="created_at" type="string">
  ISO 8601 timestamp of when the user was first identified in Cano Analytics.
</ResponseField>

<ResponseField name="last_seen_at" type="string">
  ISO 8601 timestamp of the most recent event attributed to this user.
</ResponseField>

<ResponseField name="event_count" type="integer">
  Total number of events recorded for this user.
</ResponseField>

### Request example

```bash cURL theme={null}
curl https://api.canoanalytics.io/v1/users/usr_4f8a1c \
  -H "Authorization: Bearer YOUR_API_KEY"
```

### Response — 200 OK

```json 200 OK theme={null}
{
  "id": "usr_4f8a1c",
  "traits": {
    "name": "Jordan Lee",
    "email": "jordan@example.com",
    "plan": "pro",
    "company": "Acme Corp",
    "created_at": "2024-01-10T08:00:00Z"
  },
  "created_at": "2024-01-10T08:00:00Z",
  "last_seen_at": "2024-06-15T14:32:00Z",
  "event_count": 284
}
```

***

## DELETE /v1/users/{user_id} — Delete a User

Permanently delete a user profile and all events associated with that user. Use this endpoint to fulfill GDPR right-to-erasure requests. This endpoint requires the **admin** scope.

<Warning>
  This action is **permanent and cannot be undone**. Deleting a user removes their profile and every event they have ever generated from Cano Analytics. Export any data you need to retain before calling this endpoint.
</Warning>

### Path parameters

<ParamField path="user_id" type="string" required>
  The unique identifier of the user to permanently delete.
</ParamField>

### Request example

```bash cURL theme={null}
curl -X DELETE https://api.canoanalytics.io/v1/users/usr_4f8a1c \
  -H "Authorization: Bearer YOUR_ADMIN_API_KEY"
```

### Response — 204 No Content

A successful deletion returns HTTP `204` with no response body.
