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

# Medplum setup

ConfigView reads the **administration** of your Medplum project through the Medplum FHIR API, using a **client application** that a Medplum project admin creates. The client gets an ID and a secret. ConfigView exchanges them for a one-hour token and only reads.

You will end up with **3 required secrets** (`MEDPLUM_BASE_URL`, `MEDPLUM_CLIENT_ID`, `MEDPLUM_CLIENT_SECRET`) in ConfigView when setup is complete.

> **Medplum holds protected health information (PHI). ConfigView does not read it.** The integration collects project-administration records only: the project itself, its members, client applications, bots, access policies and subscriptions. It never searches or reads a clinical resource (Patient, Observation, Encounter, Condition, MedicationRequest, DiagnosticReport, Claim or any other). Patient-portal memberships (Patient and RelatedPerson profiles) are not listed at all: ConfigView stores only a **count** of them by profile type, with no name, email or identifier. You should also give the ConfigView client an access policy that cannot read clinical data (Step 2), so the guarantee does not rest on ConfigView alone. ConfigView only reads. It never creates, changes or deletes anything in Medplum.

***

## What you need

* A Medplum project (hosted at `api.medplum.com`, or self-hosted) and a **project admin** to create a client application and an access policy
* Nothing else to enable. If the client's access policy leaves a resource type out, that collector skips itself and its table stays empty. That does not count as a failure.

***

## Step 1: Open the Medplum page in ConfigView

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

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

***

## Step 2: Create a read-only access policy

In the Medplum app, open **Project → Admin → Access Policies** and create a policy named `ConfigView read-only` with one rule for each of these resource types, each limited to **read** and **search** (no create, update or delete):

| Resource type | Used for |
| - | - |
| `Project` | The project, its features, settings and secret names |
| `ProjectMembership` | Staff, bots and client applications in the project, and counts of patient memberships |
| `ClientApplication` | Client applications and their redirect and origin settings |
| `Bot` | Bots and how they run |
| `AccessPolicy` | The access policies themselves |
| `Subscription` | Where Medplum pushes data to |

Do **not** add `Patient`, `Observation`, `Encounter` or any other clinical resource type. ConfigView never needs them. Medplum then refuses any request for clinical data from this client, whatever ConfigView does.

***

## Step 3: Create the client application

1. In Medplum open **Project → Admin → Clients** and click **New**
2. Name it `ConfigView` and save
3. Copy the **Client ID** and **Client secret**
4. Open **Project → Admin → Users** (or Members), open the ConfigView client's membership and set its **Access Policy** to `ConfigView read-only`. Do not make the client a project admin
5. Switch to the ConfigView tab and paste the ID and secret into `MEDPLUM_CLIENT_ID` and `MEDPLUM_CLIENT_SECRET` under **Credentials**, then click the save icon for each
6. In `MEDPLUM_BASE_URL` enter `https://api.medplum.com` for the hosted service, or the base URL of your self-hosted server (the address that serves `/oauth2/token` and `/fhir/R4`). Leave off `/fhir/R4`

Give ConfigView its own client rather than sharing one with a script or a bot. Then you can see exactly what it can do and rotate its secret without breaking anything else.

***

## Step 4: Connect and verify

1. Back on `https://{companyname}.configview.com/admin/integrations/medplum`, 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 | Notes |
| - | - |
| **Project** | The project: features, super-admin and strict-mode flags, names of settings and secrets (never values), registered site domains. |
| **Project Users** | Staff (practitioner), bot and client application memberships: sign-in name, admin flag, active flag, access policies. Patient and related-person memberships are never listed. |
| **Member Counts by Profile Type** | Counts of memberships per profile type (including patients and related persons), how many are admins, inactive or without an access policy. Count-only requests: no profile is read. |
| **Client Applications** | Every client application: status, redirect URL hosts, allowed origins, scopes, token lifetimes, whether a secret is set. Secrets are never stored. |
| **Bots** | Every bot: runtime, timeout, schedule, run-as-user, public webhook and system flags. Bot code is never stored. |
| **Access Policies** | Every access policy: resource types covered, wildcard, whether it can write, IP rules. Rule criteria text is not stored. |
| **Subscriptions** | What triggers each subscription, the channel, the host it posts to and whether it sends the record. Full URLs, headers and filters are not stored. |

3. Click **Verify now**. The health check reads all three secrets, gets a token, reads your project, and tries one record from each of the other areas. It only searches administration resource types.

If a check fails:

* **Token fails with 400, 401 or 403.** The client ID or secret is wrong, the secret was rotated, or the client application is disabled. Check `MEDPLUM_BASE_URL` too: a self-hosted server must answer at `<base>/oauth2/token`.
* **Project fails with 403.** The client's access policy does not allow reading `Project`. Add it to the policy from Step 2.
* **An area shows as skipped.** Medplum answered "forbidden" for that resource type. Add it to the access policy if you want that area, otherwise there is nothing to fix.

***

## Data Tables

Once the scripts run, these tables are created in your database. Each table has a `run_at` column and a `raw_json` column, which holds a trimmed copy of the record (see *What isn't collected*). Each table keeps only the newest run.

| Table | Source | Key Columns |
| - | - | - |
| `medplum_project` | `GET /fhir/R4/Project` | project\_id, name, is\_super\_admin, is\_strict\_mode, features, setting\_names, secret\_names, site\_domains |
| `medplum_project_users` | `GET /fhir/R4/ProjectMembership?profile-type=Practitioner,Bot,ClientApplication` | membership\_id, profile\_type, profile\_id, user\_name, is\_admin, is\_active, has\_access\_policy, access\_policy\_names |
| `medplum_membership_counts` | `GET /fhir/R4/ProjectMembership?_total=accurate&_count=0` (counts only) | profile\_type, total\_members, admin\_members, inactive\_members, members\_without\_policy |
| `medplum_client_applications` | `GET /fhir/R4/ClientApplication` | client\_id, name, app\_status, redirect\_hosts, has\_insecure\_redirect, has\_wildcard\_origin, has\_secret, has\_retiring\_secret |
| `medplum_bots` | `GET /fhir/R4/Bot` | bot\_id, name, runtime\_version, has\_schedule, runs\_as\_user, has\_public\_webhook, is\_system\_bot |
| `medplum_access_policies` | `GET /fhir/R4/AccessPolicy` | policy\_id, name, resource\_types, has\_wildcard\_resource, allows\_write, is\_read\_only, ip\_rule\_count |
| `medplum_subscriptions` | `GET /fhir/R4/Subscription` | subscription\_id, criteria\_resource\_type, channel\_type, endpoint\_kind, endpoint\_host, sends\_payload |

***

## Things worth knowing

**Patients are counted, never listed.** A Medplum project can have many thousands of patient-portal memberships. ConfigView asks Medplum only for the total (and how many are inactive), so no patient name, email or ID is ever requested. Staff, bot and client memberships are listed because they are the people and systems that administer and integrate with the project.

**Bots and client applications can be admins.** An admin flag on a bot or client application's membership lets code manage members, policies and clients. `medplum_project_users` shows the profile type next to the admin flag so you can see them.

**Subscriptions show where data can leave.** Each webhook or email subscription is a place records from Medplum are sent. ConfigView stores the host, the resource type that triggers it and whether it includes the record, so you can check each destination has the agreements you need.

**An access policy with a wildcard gives the whole record.** A policy with a `*` resource type, or one that lets holders create, change or delete, is listed with how many memberships hold it.

**No audit log or login history.** ConfigView does not collect Medplum audit events: they are high volume, they point at patients, and they cannot be limited to administrative actions. Sign-in history is not exposed to project admins either. Use Medplum's own audit features for those.

**Rate limit.** Medplum's hosted service allows 6,000 requests a minute per IP (60,000 on paid plans) and gives each user a FHIR point budget in which a search costs 20 points. Each ConfigView collector paces itself at 30 requests a minute, follows pagination links, and waits as long as Medplum's `RateLimit` header asks after a 429. Self-hosted servers set their own limits.

## What isn't collected

* Any clinical resource, and the name, email, identifier or profile of any Patient or RelatedPerson membership (only counts are kept)
* Client application secrets (including a retiring secret and an identity provider client secret), project secrets and setting values, and Google and reCAPTCHA site secrets. Only whether a secret is set, and the names of project secrets, are stored
* Bot source code and compiled code
* Subscription headers (which often carry an auth token), the full endpoint URL (only its host is stored) and the filter text of the subscription criteria (only the triggering resource type)
* Access policy criteria strings, and external IDs on memberships
* Audit events, login history and user configurations


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