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

# Qualtrics setup

ConfigView reads your Qualtrics brand through Qualtrics' public API (v3), using an **OAuth client that a Qualtrics Brand Administrator creates** with read-only scopes. A Brand Administrator's API token works too, but it can change everything that admin can, so the OAuth client is the recommended route.

You will end up with **3 secrets** in ConfigView (`QUALTRICS_DATACENTER`, `QUALTRICS_CLIENT_ID`, `QUALTRICS_CLIENT_SECRET`), or `QUALTRICS_DATACENTER` plus `QUALTRICS_API_TOKEN` if you use a token instead.

> **Scope of this integration today.** ConfigView reads who has a Qualtrics account and on which user type, who is a Brand Administrator, when each person last logged in, who is allowed to use the Qualtrics API, your divisions and groups and who is in them, the brand's license expiry and login statistics, the event subscriptions (webhooks) that push survey events to other systems, and the brand's activity log of sign-ins and permission changes. ConfigView never reads surveys, questions, responses, contacts, mailing lists or dashboards, and never creates or changes anything.

***

## Step 1: Open the Qualtrics page in ConfigView

Open ConfigView in a second browser tab and leave it open:

`https://{companyname}.configview.com/admin/integrations/qualtrics`

Qualtrics shows the OAuth client secret once, when you create the client, so paste it straight into ConfigView.

***

## Step 2: Find your datacenter ID

1. Sign in to Qualtrics as a **Brand Administrator**
2. Open the account menu (top right) → **Account Settings** → **Qualtrics IDs**
3. In the **User** box, copy the **Datacenter ID** (for example `iad1`, `fra1`, `syd1`)
4. Paste it into `QUALTRICS_DATACENTER` in ConfigView and click the save icon

Your brand's own host (such as `yourbrand.iad1.qualtrics.com`) also works. Use your brand's **home** datacenter: calls to another one are slower, and an OAuth client only gets tokens from the datacenter it was created in.

***

## Step 3: Create a read-only OAuth client

Every list ConfigView reads is a Brand Administrator call, and an OAuth client acts as the user who creates it. So create it as a Brand Administrator, ideally a long-lived admin account rather than a person who might leave.

1. Still in **Account Settings → Qualtrics IDs**, open **OAuth Client Manager** (on some brands it is in the **OAuth** section) and click **Create Client**
2. Name it `ConfigView` and add your IT contact email
3. Set the grant type to **Client Credentials**
4. Add these scopes and nothing else:

| Scope | What it unlocks |
| - | - |
| `read:users` | Users, user details (last login, permissions) and who the client is connected as. **Required.** |
| `read:groups` | Groups and group members |
| `read:divisions` | Divisions |
| `read:organizations` | Brand details: license expiry, survey counts, login statistics |
| `read:subscriptions` | Event subscriptions (webhooks) |
| `read:activity_logs` | The activity log of sign-ins and admin changes |

5. Click **Create client** and copy the **Client ID** and **Client Secret**. Qualtrics will not show the secret again
6. Paste them into `QUALTRICS_CLIENT_ID` and `QUALTRICS_CLIENT_SECRET` in ConfigView and click the save icon for each

Leaving out an optional scope is fine: the collectors that need it skip quietly and the rest still run. ConfigView asks Qualtrics for each scope by name, never `manage:all`.

**Using an API token instead.** If your brand cannot create OAuth clients, a Brand Administrator can use **Account Settings → Qualtrics IDs → API → Generate Token** and paste it into `QUALTRICS_API_TOKEN`. The token carries all of that admin's rights, including changes, and generating a new one immediately breaks anything still using the old one. ConfigView ignores the token when the OAuth client ID and secret are set.

**Activity log access.** Reading the activity log also needs the admin's account to have Qualtrics' activity log (audit) access, which some licenses include and others add on. Without it, only the Activity Log collector skips.

**To revoke ConfigView's access**, delete the client in OAuth Client Manager (or generate a new API token).

***

## Step 4: Connect and verify

1. Back on `https://{companyname}.configview.com/admin/integrations/qualtrics`, confirm the credentials show as saved
2. Click **Connect**. ConfigView creates its tables and schedules every collector at your default run time. Stop any you don't want under **Collectors**:

| Script | Needs | Notes |
| - | - | - |
| **Users** | `read:users` | Every account in the brand, including disabled ones: username, email, name, user type, division and account status. |
| **User Details (last login)** | `read:users` | Per person: last login, created and expiry dates, password last changed, sign-in identity provider, response counts, and the permissions that are on, including API access. Refreshes up to 1,500 people a run, never-seen and stalest first. Runs after Users. |
| **Groups** | `read:groups` | Groups, their type, division, whether membership is automatic, and who created them. |
| **Group Members** | `read:groups` | Who is in each group, with user type and status. |
| **Divisions** | `read:divisions` | Each division in use: name, status, creator, response counts, user count and division-level permissions. Runs after Users and Groups. |
| **Organization (brand)** | `read:organizations` | Brand type, status, license expiry, survey and response counts, how many users logged in recently or never, and which account ConfigView is connected as. |
| **Event Subscriptions (webhooks)** | `read:subscriptions` | Where Qualtrics pushes events such as completed responses: destination host, plain http or not, events, encryption, successful deliveries. |
| **Activity Log** | `read:activity_logs` | Sign-ins (including failed, proxy and SSO ones, with IP, location, browser and second factor), accounts created, changed or deleted, user-type and permission changes, role changes and brand setting changes. Kept permanently. |

3. Click **Verify now**. The health check confirms the secrets, gets a token, checks who the client is connected as and whether that is a Brand Administrator, reads a page of users, then reports groups, event subscriptions, the activity log and the brand details as ok or skipped.

If a check fails:

* **Token request fails with `invalid_client`.** The client ID or secret is wrong, or the client was created in a different datacenter than `QUALTRICS_DATACENTER`.
* **Token request fails with `invalid_scope` on `read:users`.** The client was created without `read:users`. Edit the client's scopes or create a new one.
* **`/users` returns 403.** The client (or token) belongs to someone who is not a Brand Administrator. Recreate it as a Brand Administrator.
* **A collector is skipped with "not granted read:…".** That scope is missing from the client. Add it if you want that data.
* **Activity Log skipped with 403.** The admin's license doesn't include activity log access.
* **429.** Qualtrics' per-brand limit is spent for the moment, usually by a survey export or another integration. The next run will be fine.

***

## Data Tables

Once the scripts run, these tables are created in your database. Each includes a `run_at` column. Snapshot tables keep only the newest run.

| Table | Source | Key Columns |
| - | - | - |
| `qualtrics_users` | `GET /API/v3/users` | user\_id, username, email, first\_name, last\_name, user\_type, user\_type\_name, is\_brand\_admin, division\_id, account\_status |
| `qualtrics_user_details` | `GET /API/v3/users/{userId}` | user\_id, username, email, user\_type, user\_type\_name, is\_brand\_admin, organization\_id, division\_id, account\_status, language, time\_zone, unsubscribed, account\_creation\_date, account\_expiration\_date, password\_last\_changed\_date, password\_expiration\_date, last\_login\_date, identity\_provider, response\_count\_auditable, response\_count\_generated, response\_count\_deleted, api\_access, permissions\_on, permissions\_json |
| `qualtrics_groups` | `GET /API/v3/groups`, `GET /API/v3/groups/{groupId}` | group\_id, group\_name, group\_type, organization\_id, division\_id, auto\_membership, creation\_date, creator\_id |
| `qualtrics_group_members` | `GET /API/v3/groups/{groupId}/members` | group\_id, group\_name, user\_id, username, email, first\_name, last\_name, user\_type, user\_type\_name, division\_id, account\_status |
| `qualtrics_divisions` | `GET /API/v3/divisions/{divisionId}` | division\_id, division\_name, organization\_id, division\_status, creation\_date, creator\_id, user\_count, response\_count\_auditable, response\_count\_generated, response\_count\_deleted, permissions\_json |
| `qualtrics_organization` | `GET /API/v3/whoami`, `GET /API/v3/organizations/{brandId}` | organization\_id, organization\_name, base\_url\_host, organization\_type, organization\_status, creation\_date, expiration\_date, total\_surveys, active\_surveys, response\_count\_auditable, response\_count\_generated, response\_count\_deleted, total\_users, logins\_past\_1\_day … logins\_past\_120\_days, logins\_ever, never\_logged\_in, datacenter, connected\_as\_user\_id, connected\_as\_username, connected\_as\_account\_type |
| `qualtrics_event_subscriptions` | `GET /API/v3/eventsubscriptions` | subscription\_id, subscription\_scope, topics, publication\_host, publication\_scheme, encrypted, successful\_calls |
| `qualtrics_activity_log` | `GET /API/v3/logs` | event\_id, activity\_type, event\_time, brand\_id, user\_id, username, agent\_user\_id, action\_name, change\_type, is\_successful, failure\_reason, is\_proxy\_login, proxy\_reason, product, ip\_address, country\_code, region, city, auth\_method, second\_factor, user\_agent, operating\_system, device\_family, role\_id, role\_name, member\_id, permission\_slug, permission\_effect, prev\_user\_type, new\_user\_type, changed\_keys, changes\_json, source\_service |

**`user_type`** is Qualtrics' user type ID. Qualtrics' built-in types get a name in `user_type_name` (for example `UT_BRANDADMIN` is Brand Administrator, `UT_PARTICIPANT` is Participant). Types your brand created have IDs like `UT_4dSkJx0YwB2nQ1a`. The API doesn't return their names, so `user_type_name` is empty. Look the ID up under **Admin → User Types**.

**`api_access`** is 1 when the user's **Access API** permission is on, so they can generate an API token. `permissions_on` lists every permission switched on for the user.

***

## Things worth knowing

**User Details refresh in rotation.** The users list has no last-login date, so ConfigView reads one user at a time and refreshes up to 1,500 a run (`QUALTRICS_DETAIL_LOOKUPS_PER_RUN`), never-seen and stalest first. A 20,000-account university brand is fully refreshed every 14 runs. `run_at` on that table is when each person's row was last refreshed, and people deleted from Qualtrics are removed from it.

**The activity log is a permanent ledger.** Qualtrics keeps activity logs for a limited time. ConfigView stores each event once and never prunes. The first run reaches back 30 days (`QUALTRICS_ACTIVITY_BACKFILL_DAYS`), and later runs continue from the newest stored event. By default it reads sign-ins, user changes, user and role permission changes, role membership changes and brand setting changes. API-call events (`api_access`) are left out because there is one per API call. Add them with `QUALTRICS_ACTIVITY_TYPES` if you want to see which accounts use the API.

**API calls are shared with your other integrations.** Qualtrics allows 3,000 calls a minute per brand across every integration, and fewer on some endpoints (groups 600, event subscriptions 120, brand details 5). ConfigView paces itself at a fraction of each.

**Divisions come from your users and groups.** Qualtrics has no "list divisions" call, so ConfigView reads the divisions your users and groups belong to. An empty division with no users or groups isn't collected.

## What isn't collected

* Surveys, survey questions and flows, responses, response exports, files and quotas
* Contacts, mailing lists, XM Directory data, distributions and samples
* Dashboards, reports and tickets
* Full event subscription URLs (only the host is kept, since URLs can carry tokens)
* Password hashes and the sign-in URL from activity-log events; password change and reset events aren't requested
* API tokens and OAuth secrets of any user


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.