> For the complete documentation index, see [llms.txt](https://docs.bloodgpt.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.bloodgpt.com/integration-guides/portal-setup.md).

# Portal Setup Guide

Detailed guide to setting up and configuring the white-label Patient Portal.

This guide walks you through configuring the BloodGPT Patient Portal with your branding and managing patient access.

## Prerequisites

* Active BloodGPT account with Portal access
* Your logo file (PNG or SVG)
* Brand colors (hex codes)
* List of patients (email + external ID)

## Step 1: Configure Branding

Access your organization settings in the BloodGPT dashboard.

### Required Settings

| Setting           | Description            | Example            |
| ----------------- | ---------------------- | ------------------ |
| **Display Name**  | Name shown to patients | "HealthFirst Labs" |
| **Logo**          | Your logo image        | 200x50px PNG/SVG   |
| **Primary Color** | Brand accent color     | `#2563eb`          |

### Optional Settings

| Setting              | Description      | Default                |
| -------------------- | ---------------- | ---------------------- |
| **Portal Subdomain** | Custom subdomain | `yourorg.bloodgpt.com` |
| **Support Email**    | Shown in emails  | Your org email         |
| **Support Phone**    | Shown in portal  | —                      |

### Logo Requirements

* **Format:** PNG or SVG
* **Size:** Recommended 200x50px (or similar aspect ratio)
* **Background:** Transparent preferred
* **File size:** Under 500KB

## Step 2: Register Patients

Patients must be registered before they can access results. Each patient needs:

* **Email** — for magic link delivery
* **External Patient ID** — matches `patient_id` in API requests

{% hint style="warning" %}
**Important:** The `patient_id` you send in API requests must match a registered patient's External ID. Unregistered patients won't receive portal access.
{% endhint %}

### Option A: Manual Registration

Add patients one at a time via the dashboard:

1. Navigate to **Portal → Patients**
2. Click **Add Patient**
3. Enter email and external ID
4. Save

### Option B: CSV Import

Bulk import patients from a spreadsheet:

**CSV Format:**

```csv
email,external_patient_id
john.doe@email.com,PAT-001
jane.smith@email.com,PAT-002
bob.wilson@email.com,PAT-003
```

**Steps:**

1. Prepare CSV file with headers: `email,external_patient_id`
2. Navigate to **Portal → Patients → Import**
3. Upload CSV file
4. Review and confirm

### Option C: API Registration

Programmatically register patients:

```bash
curl -X POST https://sandbox.bloodgpt.com/api/v1/patients \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "patient@example.com",
    "patient_id": "PAT-001",
    "name": "John Doe"
  }'
```

## Step 3: Test the Flow

Before going live, verify the complete flow:

### 1. Register a Test Patient

Use your own email for testing:

```bash
curl -X POST https://sandbox.bloodgpt.com/api/v1/patients \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "your-email@example.com",
    "patient_id": "TEST-PAT-001"
  }'
```

### 2. Submit a Test Result

```bash
curl -X POST https://sandbox.bloodgpt.com/api/v1/process \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "patient_id": "TEST-PAT-001",
    "external_id": "TEST-RESULT-001",
    "patient_info": {"birth_date": "1985-01-01", "gender": "male"},
    "payload": {
      "parameters": [
        {"name": "Glucose", "value": 95, "unit": "mg/dL", "range": "70-100"}
      ]
    }
  }'
```

### 3. Verify Email Delivery

Check your inbox for the magic link email.

### 4. Test Portal Access

Click the magic link and verify:

* Your logo appears
* Brand colors are correct
* Results display properly
* Mobile view works

## Step 4: Go Live

Once testing is complete:

1. **Switch to production** — Move from the sandbox URL (`https://sandbox.bloodgpt.com`) to the production base URL issued by BloodGPT (production access is granted on request)
2. **Import all patients** — Ensure patient list is complete
3. **Update your LIS integration** — Point to production API
4. **Monitor first results** — Verify emails are delivered

## Patient Experience

### Magic Link Email

Patients receive an email like:

> **Subject:** Sign in to HealthFirst Labs Patient Portal
>
> Click the button below to view your blood test results. This link expires in 15 minutes.
>
> \[View My Results]

### Portal Features

What patients see:

* **Results overview** — All values with status indicators
* **AI interpretation** — Plain language explanation
* **Recommendations** — Personalized next steps
* **History** — Previous test results (if available)

### No Password Required

* Magic links provide secure, frictionless access
* New link sent for each login
* Links expire after 15 minutes
* Patients can request new link anytime

### With Doctor Validation

If [Doctor Validation](/integration-guides/doctor-validation.md) is enabled for your organization, the magic link email is sent only **after** a doctor approves the report. Patients won't receive results until a physician has reviewed them.

## Troubleshooting

### Patient Didn't Receive Email

1. Check spam/junk folder
2. Verify email address in patient registration
3. Ensure `patient_id` in API request matches registered ID
4. Check email delivery logs in dashboard

### Branding Not Showing

1. Clear browser cache
2. Verify logo was uploaded successfully
3. Check that settings were saved
4. Wait a few minutes for CDN propagation

### Patient Can't Access Results

1. Verify patient is registered
2. Check `patient_id` matches exactly (case-sensitive)
3. Ensure test was processed successfully
4. Try sending a new magic link

## Security Considerations

| Feature            | Description                                                                                                                                                                                                                                                                                                                                              |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Magic links**    | Single-use sign-in tokens that expire 15 minutes after they are issued. The token is stored only as a SHA-256 hash, so a database copy cannot be replayed as a login                                                                                                                                                                                     |
| **HTTPS only**     | All portal traffic encrypted                                                                                                                                                                                                                                                                                                                             |
| **No passwords**   | Nothing for patients to manage or leak                                                                                                                                                                                                                                                                                                                   |
| **Sessions**       | Session cookies are `HttpOnly`, `Secure`, and `SameSite=Lax`, and expire 30 days after sign-in. There is no idle timeout — a session lives until it expires or the patient signs out                                                                                                                                                                     |
| **Not indexable**  | Portal token pages are served with `X-Robots-Tag: noindex, nofollow` and `Referrer-Policy: no-referrer`, so results stay out of search engines and tokens are not leaked in the referer header                                                                                                                                                           |
| **Shared reports** | A patient-created share link addresses one report, not the patient profile. The patient picks a lifetime (1, 7, 30, 90, or 365 days; 7 preselected), capped by your organization's maximum — 30 days unless you change it — and can revoke the link at any time. Missing, expired, and revoked tokens all return the same 404, so links cannot be probed |

{% hint style="success" %}
**Support:** Need help with portal setup? Contact <contact@bloodgpt.com>
{% endhint %}
