Skip to main content
PathMon

Chapter 2 of 6

gethomepage Dashboard Card

Updated Read the full guide

PatchMon exposes a dedicated read-only endpoint designed to be consumed by a GetHomepage (formerly Homepage) customapi widget. Drop a PatchMon card into your existing homepage to see total hosts, pending updates, and security updates at a glance.

Related pages:

  • Integration API Documentation: the generic scoped API (a different integration type)
  • Users, Roles and RBAC: permission required to create the API key

At a glance

  • Endpoint: GET /api/v1/gethomepage/stats
  • Auth: HTTP Basic, using a PatchMon-issued API key dedicated to the GetHomepage integration
  • Widget type: customapi in GetHomepage
  • Fields available: 8 core metrics + a top-3 OS breakdown + a full os_distribution array
  • Rate limit: shares the standard API rate limit; GetHomepage polls every 60 seconds, well within the limit

Default widget

Out of the box the widget shows three metrics:

  • Total Hosts
  • Hosts Needing Updates
  • Security Updates

Additional metrics can be added by editing the mappings: in your GetHomepage services.yml. See Configuration options below.


Prerequisites

  • A running PatchMon 2.x instance reachable from the machine running GetHomepage.
  • GetHomepage already installed and rendering at least one page.
  • Network path between GetHomepage and PatchMon on HTTP or HTTPS. HTTPS is strongly recommended.
  • PatchMon admin access (you need can_manage_settings to create API keys).

Setup

Step 1: Create a GetHomepage API key

  1. Sign in to PatchMon as an admin.
  2. Go to Settings → Integrations.
  3. Open the GetHomepage tab.
  4. Click New API Key and fill in:
    • Token Name: e.g. GetHomepage dashboard.
    • Allowed IP Addresses (optional): restrict to the IP of the machine running GetHomepage.
    • Expiration Date (optional): set one if this is a temporary key.
  5. Click Create Token.

Step 2: Copy the credentials

A success modal is shown with:

  • Token Key: the API username.
  • Token Secret: the API password. Shown only once. Save it immediately.
  • Base64-encoded credentials: pre-built Authorization: Basic value, ready to paste.
  • Complete widget configuration: a ready-to-drop-in YAML snippet.

Click Copy Config to copy the full YAML block. The secret is never retrievable again after you close this modal. If you lose it, you have to delete the key and create a new one.

Step 3: Configure GetHomepage

Option A: Paste the copied YAML (quickest)
  1. Open your GetHomepage services.yml.
  2. Paste the YAML block that PatchMon gave you.
  3. Save the file.
  4. Restart GetHomepage.

The YAML looks like this:

- PatchMon:
    href: https://patchmon.example.com
    description: PatchMon Statistics
    icon: https://patchmon.example.com/assets/favicon.svg
    widget:
      type: customapi
      url: https://patchmon.example.com/api/v1/gethomepage/stats
      headers:
        Authorization: Basic <base64_encoded_credentials>
      mappings:
        - field: total_hosts
          label: Total Hosts
        - field: hosts_needing_updates
          label: Needs Updates
        - field: security_updates
          label: Security Updates
Option B: Build it by hand
  1. Encode your credentials:

    echo -n "YOUR_TOKEN_KEY:YOUR_TOKEN_SECRET" | base64
    
  2. Paste the widget into services.yml, replacing <your_base64_credentials> with the result:

    - PatchMon:
        href: https://patchmon.example.com
        description: PatchMon Statistics
        icon: https://patchmon.example.com/assets/favicon.svg
        widget:
          type: customapi
          url: https://patchmon.example.com/api/v1/gethomepage/stats
          headers:
            Authorization: Basic <your_base64_credentials>
          mappings:
            - field: total_hosts
              label: Total Hosts
            - field: hosts_needing_updates
              label: Needs Updates
            - field: security_updates
              label: Security Updates
    
  3. Restart GetHomepage:

    docker restart gethomepage
    # or
    systemctl restart gethomepage
    

Configuration options

Customising the fields displayed

The default configuration displays 3 metrics. You can add more. PatchMon returns 8 numeric metrics and the top-3 OS breakdown, and the widget supports 6–8 comfortably before it becomes cluttered.

Each mappings entry has two parts:

  • field: the JSON key returned by the PatchMon API (case-sensitive, exactly as listed below)
  • label: the human-readable label rendered by GetHomepage

Available fields

Field Type Description Included by default
total_hosts Number Total hosts in PatchMon, matching the Total Hosts card on the dashboard Yes
hosts_needing_updates Number Hosts with at least one outdated package Yes
security_updates Number Total security updates available across all hosts Yes
up_to_date_hosts Number Hosts with zero outdated packages No
total_outdated_packages Number Sum of all outdated packages across hosts No
hosts_with_security_updates Number Hosts requiring at least one security patch No
total_repos Number Active repositories being monitored No
recent_updates_24h Number Successful updates in the last 24 hours No
top_os_1_name String Name of the most common OS (e.g. "Ubuntu") No (use label instead, see below)
top_os_1_count Number Count of the most common OS No
top_os_2_name String Name of the 2nd most common OS No
top_os_2_count Number Count of the 2nd most common OS No
top_os_3_name String Name of the 3rd most common OS No
top_os_3_count Number Count of the 3rd most common OS No
os_distribution Array Full OS breakdown (advanced use only; GetHomepage cannot render arrays directly) No
last_updated String (ISO 8601) Timestamp the stats were generated No

The top_os_*_name string fields render poorly in customapi widgets. Use the corresponding _count fields and put the OS name in the label:. See Displaying OS distribution.

Quick recipe: add a fourth metric

Before:

mappings:
  - field: total_hosts
    label: Total Hosts
  - field: hosts_needing_updates
    label: Needs Updates
  - field: security_updates
    label: Security Updates

After:

mappings:
  - field: total_hosts
    label: Total Hosts
  - field: hosts_needing_updates
    label: Needs Updates
  - field: security_updates
    label: Security Updates
  - field: recent_updates_24h      # newly added
    label: Updated (24h)

Save, restart GetHomepage, and you've gone from 3 to 4 metrics.


Example widget configurations

All examples assume you've already populated the Authorization header with your encoded credentials.

Security-focused widget

widget:
  type: customapi
  url: https://patchmon.example.com/api/v1/gethomepage/stats
  headers:
    Authorization: Basic <credentials>
  mappings:
    - field: security_updates
      label: Security Patches
    - field: hosts_with_security_updates
      label: Hosts at Risk
    - field: hosts_needing_updates
      label: Total Pending

Repository / coverage widget

widget:
  type: customapi
  url: https://patchmon.example.com/api/v1/gethomepage/stats
  headers:
    Authorization: Basic <credentials>
  mappings:
    - field: total_repos
      label: Repositories
    - field: total_hosts
      label: Managed Hosts
    - field: up_to_date_hosts
      label: Up-to-Date

Activity widget

widget:
  type: customapi
  url: https://patchmon.example.com/api/v1/gethomepage/stats
  headers:
    Authorization: Basic <credentials>
  mappings:
    - field: recent_updates_24h
      label: Updated (24h)
    - field: hosts_needing_updates
      label: Pending Updates
    - field: up_to_date_hosts
      label: Fully Patched

Maximum-information widget (all 8 numeric metrics)

widget:
  type: customapi
  url: https://patchmon.example.com/api/v1/gethomepage/stats
  headers:
    Authorization: Basic <credentials>
  mappings:
    - field: total_hosts
      label: Total Hosts
    - field: hosts_needing_updates
      label: Needs Updates
    - field: up_to_date_hosts
      label: Up-to-Date
    - field: security_updates
      label: Security Updates
    - field: hosts_with_security_updates
      label: Security Hosts
    - field: total_outdated_packages
      label: Outdated Packages
    - field: total_repos
      label: Repositories
    - field: recent_updates_24h
      label: Updated (24h)

Note this widget will be quite tall. Keep it to 3–5 metrics for most layouts.

Multiple environments

# Production - security-focused
- PatchMon Prod:
    href: https://patchmon-prod.example.com
    description: Production Patches
    icon: https://patchmon-prod.example.com/assets/favicon.svg
    widget:
      type: customapi
      url: https://patchmon-prod.example.com/api/v1/gethomepage/stats
      headers:
        Authorization: Basic <prod_credentials>
      mappings:
        - field: total_hosts
          label: Hosts
        - field: security_updates
          label: Security
        - field: hosts_needing_updates
          label: Pending

# Development - package-focused
- PatchMon Dev:
    href: https://patchmon-dev.example.com
    description: Development Patches
    icon: https://patchmon-dev.example.com/assets/favicon.svg
    widget:
      type: customapi
      url: https://patchmon-dev.example.com/api/v1/gethomepage/stats
      headers:
        Authorization: Basic <dev_credentials>
      mappings:
        - field: total_hosts
          label: Hosts
        - field: total_outdated_packages
          label: Packages
        - field: up_to_date_hosts
          label: Updated

Displaying OS distribution

Step 1: Find out your top 3 operating systems

curl -s -H "Authorization: Basic YOUR_BASE64_CREDENTIALS" \
  https://patchmon.example.com/api/v1/gethomepage/stats \
  | jq '{top_os_1_name, top_os_1_count, top_os_2_name, top_os_2_count, top_os_3_name, top_os_3_count}'

Sample output:

{
  "top_os_1_name": "Ubuntu",
  "top_os_1_count": 35,
  "top_os_2_name": "Debian",
  "top_os_2_count": 18,
  "top_os_3_name": "Rocky Linux",
  "top_os_3_count": 12
}

Step 2: Add the counts to the widget, using the names as labels

mappings:
  - field: total_hosts
    label: Total Hosts
  - field: top_os_1_count
    label: Ubuntu          # from top_os_1_name
  - field: top_os_2_count
    label: Debian          # from top_os_2_name
  - field: top_os_3_count
    label: Rocky Linux     # from top_os_3_name

Step 3: Restart GetHomepage

docker restart gethomepage
# or
systemctl restart gethomepage

The widget now shows your infrastructure OS breakdown. If your top 3 OSes change over time, update the labels; PatchMon will reorder the counts automatically based on actual host counts.

Custom icon

# PatchMon logo
icon: https://patchmon.example.com/assets/favicon.svg
icon: https://patchmon.example.com/assets/logo_dark.png
icon: https://patchmon.example.com/assets/logo_light.png

# GetHomepage built-in icon
icon: server

# Local icon inside your GetHomepage image / volume
icon: /icons/patchmon.png

API reference

Endpoints

Method Path Description
GET /api/v1/gethomepage/stats Returns the widget payload described above
GET /api/v1/gethomepage/health Simple liveness probe. Returns status: "ok", the current timestamp, and the name of the API key used.

Authentication

  • Type: HTTP Basic Authentication
  • Format: Authorization: Basic <base64(token_key:token_secret)>
  • Token type: gethomepage (enforced server-side; a credential created under the API tab won't work here, and vice versa)

Stats response

{
  "total_hosts": 42,
  "total_outdated_packages": 156,
  "total_repos": 12,
  "hosts_needing_updates": 15,
  "up_to_date_hosts": 27,
  "security_updates": 23,
  "hosts_with_security_updates": 8,
  "recent_updates_24h": 34,
  "os_distribution": [
    { "name": "Ubuntu",     "count": 20, "os_type": "linux", "os_version": "22.04" },
    { "name": "Debian",     "count": 12, "os_type": "linux", "os_version": "12" },
    { "name": "Rocky Linux", "count": 10, "os_type": "linux", "os_version": "9" }
  ],
  "top_os_1_name": "Ubuntu",
  "top_os_1_count": 20,
  "top_os_2_name": "Debian",
  "top_os_2_count": 12,
  "top_os_3_name": "Rocky Linux",
  "top_os_3_count": 10,
  "last_updated": "2026-04-24T12:34:56Z"
}

Health response

{
  "status": "ok",
  "timestamp": "2026-04-24T12:34:56Z",
  "api_key": "GetHomepage dashboard"
}

Managing API keys

Viewing existing keys

Go to Settings → Integrations → GetHomepage. For each key you see:

  • Token name
  • Creation date
  • Last-used timestamp
  • Active / Inactive status
  • Expiration date (if set)

Disable / Enable / Delete

  • Disable / Enable: toggle the button on the row to temporarily block or restore access without deleting the credential.
  • Delete: click the trash icon. This is permanent; any widget using that key will start returning 401.

Security features

  • IP restrictions: per-key allowlist (CIDRs supported).
  • Expiration dates: automatic sunset.
  • Last-used tracking: spot keys that have silently stopped working, or suspicious usage.
  • One-time secret display: the secret is shown once, at creation. Never again.

Troubleshooting

Error: "Missing or invalid authorization header"

GetHomepage is not sending the Authorization header correctly.

  • Verify the headers: section is properly indented in services.yml.
  • Re-encode the credentials; make sure you used -n with echo so no trailing newline ends up in the base64.
  • Confirm you're using type: customapi, as other widget types ignore arbitrary headers.

Error: "Invalid API key"

The key does not exist in PatchMon.

  • Check Settings → Integrations → GetHomepage for the key.
  • Re-create the key if it's missing, update the GetHomepage config with the new credentials.

Error: "API key is disabled" / "API key has expired"

Enable the key, or create a new one with a later expiration.

Error: "IP address not allowed"

Your GetHomepage instance's outbound IP is not in the credential's allowlist. Either add it, or remove the allowlist if not needed.

Widget shows nothing

Work through this checklist:

  • Can GetHomepage reach PatchMon at all? Test with curl from inside the GetHomepage container: curl -v https://patchmon.example.com/api/v1/gethomepage/health -H "Authorization: Basic ..."
  • Is the API key active and not expired?
  • Is the base64 credential correct?
  • Is services.yml valid YAML? (run yamllint services.yml if unsure)
  • Has GetHomepage been restarted since the last change?
  • Check GetHomepage's container logs for error messages.

Testing the endpoint directly

# Step 1: encode
echo -n "your_key:your_secret" | base64

# Step 2: test
curl -H "Authorization: Basic YOUR_BASE64" \
     https://patchmon.example.com/api/v1/gethomepage/stats | jq

Every numeric field in the response (including top_os_*_count) can be used in a widget mapping.


Security best practices

  • Always use HTTPS. The credentials are sent on every 60-second poll. Don't put them on the wire in the clear.
  • IP-restrict the key to the GetHomepage instance's IP.
  • Give the key an expiration and rotate it as part of your normal credential rotation.
  • Monitor the last-used timestamp to spot suspicious activity.
  • One key per GetHomepage instance if you're running several, to make rotation and revocation easier.
  • Store services.yml with appropriate file permissions on the GetHomepage host.

Integration architecture

┌──────────────────┐
│   GetHomepage    │
│    Dashboard     │
└────────┬─────────┘
         │
         │ HTTP(S) GET, every 60s
         │ Authorization: Basic <base64>
         │
         ▼
┌──────────────────┐
│    PatchMon      │
│   API server     │
│                  │
│ /api/v1/         │
│ gethomepage/     │
│   stats          │
└────────┬─────────┘
         │
         │ Aggregate query
         │
         ▼
┌──────────────────┐
│   PostgreSQL     │
│                  │
│  - Hosts         │
│  - Packages      │
│  - Updates       │
│  - Repositories  │
└──────────────────┘

Rate limiting

The /api/v1/gethomepage/* endpoints are subject to PatchMon's general API rate limit of 100 requests per 15 minutes per IP by default. GetHomepage's default poll interval of 60 seconds sits well within this limit (15 requests per 15 minutes). If you lower GetHomepage's poll interval aggressively, you may start hitting 429 Too Many Requests; stay above 10 seconds.


Support and resources