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

# Doohick Users API: Manage Profiles and Workspace Members

> Use the Doohick Users API to retrieve and update your profile, fetch your role and workspace ID, and list all members in your workspace.

The Users API lets you retrieve and update the authenticated user's profile and list every member belonging to your workspace. All requests must include a valid Bearer token in the `Authorization` header and target the base URL `https://api.doohick.com/v1`.

***

## `GET /users/me`

Retrieve the authenticated user's profile. Use this endpoint to fetch the current user's ID, email, role, and workspace association.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET https://api.doohick.com/v1/users/me \
    -H "Authorization: Bearer dh_live_XXXXXXXXXXXXXXXXXXXX"
  ```

  ```javascript Node.js theme={null}
  const response = await fetch('https://api.doohick.com/v1/users/me', {
    method: 'GET',
    headers: {
      'Authorization': 'Bearer dh_live_XXXXXXXXXXXXXXXXXXXX'
    }
  });

  const { data } = await response.json();
  console.log(data);
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      'https://api.doohick.com/v1/users/me',
      headers={'Authorization': 'Bearer dh_live_XXXXXXXXXXXXXXXXXXXX'}
  )

  data = response.json()['data']
  print(data)
  ```
</CodeGroup>

**Response `200 OK`**

```json JSON theme={null}
{
  "data": {
    "id": "usr_abc123",
    "email": "you@example.com",
    "name": "Jane Doe",
    "role": "admin",
    "workspace_id": "ws_xyz789",
    "created_at": "2024-01-15T10:00:00Z",
    "updated_at": "2024-03-20T14:30:00Z"
  }
}
```

<ResponseField name="data" type="object" required>
  The authenticated user object.

  <Expandable title="data">
    <ResponseField name="id" type="string">
      Unique identifier for the user, prefixed with `usr_`.
    </ResponseField>

    <ResponseField name="email" type="string">
      The user's email address. This value is immutable after account creation.
    </ResponseField>

    <ResponseField name="name" type="string">
      The user's display name.
    </ResponseField>

    <ResponseField name="role" type="string">
      The user's role within the workspace. One of `admin`, `member`, or `viewer`.
    </ResponseField>

    <ResponseField name="workspace_id" type="string">
      The ID of the workspace this user belongs to, prefixed with `ws_`.
    </ResponseField>

    <ResponseField name="created_at" type="string">
      ISO 8601 timestamp indicating when the user account was created.
    </ResponseField>

    <ResponseField name="updated_at" type="string">
      ISO 8601 timestamp indicating when the user account was last updated.
    </ResponseField>
  </Expandable>
</ResponseField>

***

## `PATCH /users/me`

Update the authenticated user's profile. You can change the display name and timezone. All other fields are read-only.

<ParamField body="name" type="string">
  The new display name for the user. Must be between 1 and 100 characters.
</ParamField>

<ParamField body="timezone" type="string">
  A valid IANA timezone string, such as `America/New_York` or `Europe/London`. Doohick uses this value to localize timestamps in the dashboard and notification emails.
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PATCH https://api.doohick.com/v1/users/me \
    -H "Authorization: Bearer dh_live_XXXXXXXXXXXXXXXXXXXX" \
    -H "Content-Type: application/json" \
    -d '{"name": "Jane Smith", "timezone": "Europe/London"}'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch('https://api.doohick.com/v1/users/me', {
    method: 'PATCH',
    headers: {
      'Authorization': 'Bearer dh_live_XXXXXXXXXXXXXXXXXXXX',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ name: 'Jane Smith', timezone: 'Europe/London' })
  });

  const { data } = await response.json();
  console.log(data);
  ```

  ```python Python theme={null}
  import requests

  response = requests.patch(
      'https://api.doohick.com/v1/users/me',
      headers={
          'Authorization': 'Bearer dh_live_XXXXXXXXXXXXXXXXXXXX',
          'Content-Type': 'application/json'
      },
      json={'name': 'Jane Smith', 'timezone': 'Europe/London'}
  )

  data = response.json()['data']
  print(data)
  ```
</CodeGroup>

**Response `200 OK`**

The response returns the full updated user object with the same shape as `GET /users/me`.

```json JSON theme={null}
{
  "data": {
    "id": "usr_abc123",
    "email": "you@example.com",
    "name": "Jane Smith",
    "role": "admin",
    "workspace_id": "ws_xyz789",
    "created_at": "2024-01-15T10:00:00Z",
    "updated_at": "2024-03-21T09:15:00Z"
  }
}
```

<Note>
  Only include the fields you want to change. Omitted fields remain unchanged.
</Note>

***

## `GET /users`

List all members of your workspace. Use the `limit` and `offset` query parameters to paginate through large teams.

<ParamField query="limit" type="integer" default="20">
  The maximum number of users to return in a single response. Accepted range is `1`–`100`.
</ParamField>

<ParamField query="offset" type="integer" default="0">
  The number of users to skip before returning results. Use this in combination with `limit` to paginate through all workspace members.
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.doohick.com/v1/users?limit=20&offset=0" \
    -H "Authorization: Bearer dh_live_XXXXXXXXXXXXXXXXXXXX"
  ```

  ```javascript Node.js theme={null}
  const response = await fetch('https://api.doohick.com/v1/users?limit=20&offset=0', {
    method: 'GET',
    headers: {
      'Authorization': 'Bearer dh_live_XXXXXXXXXXXXXXXXXXXX'
    }
  });

  const { data, meta } = await response.json();
  console.log(`Showing ${data.length} of ${meta.total} members`);
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      'https://api.doohick.com/v1/users',
      headers={'Authorization': 'Bearer dh_live_XXXXXXXXXXXXXXXXXXXX'},
      params={'limit': 20, 'offset': 0}
  )

  result = response.json()
  print(f"Showing {len(result['data'])} of {result['meta']['total']} members")
  ```
</CodeGroup>

**Response `200 OK`**

```json JSON theme={null}
{
  "data": [
    {
      "id": "usr_abc123",
      "email": "you@example.com",
      "name": "Jane Doe",
      "role": "admin",
      "workspace_id": "ws_xyz789",
      "created_at": "2024-01-15T10:00:00Z",
      "updated_at": "2024-03-20T14:30:00Z"
    },
    {
      "id": "usr_def456",
      "email": "colleague@example.com",
      "name": "John Smith",
      "role": "member",
      "workspace_id": "ws_xyz789",
      "created_at": "2024-02-10T08:00:00Z",
      "updated_at": "2024-02-10T08:00:00Z"
    }
  ],
  "meta": {
    "total": 42,
    "limit": 20,
    "offset": 0
  }
}
```

<ResponseField name="data" type="array">
  An array of user objects. Each object has the same shape as the response from `GET /users/me`.
</ResponseField>

<ResponseField name="meta" type="object">
  Pagination metadata for the response.

  <Expandable title="meta">
    <ResponseField name="meta.total" type="integer">
      The total number of workspace members across all pages.
    </ResponseField>

    <ResponseField name="meta.limit" type="integer">
      The page size applied to this response.
    </ResponseField>

    <ResponseField name="meta.offset" type="integer">
      The number of records skipped before this page.
    </ResponseField>
  </Expandable>
</ResponseField>

<Tip>
  To fetch the next page, increment `offset` by the value of `limit`. Stop paginating when `offset >= meta.total`.
</Tip>
