Skip to content

Home Assistant Integration

DredBaron edited this page Sep 12, 2026 · 1 revision

Overview

OpenMTG can push trade and wishlist price-alert events to Home Assistant, and let Home Assistant pull your live collection stats back, using per-user webhook credentials. An admin must enable the integration before anyone can use it as it is off by default.

Two independent directions, tied together by one credential:

  • Push (OpenMTG -> Home Assistant): trade and wishlist-target events POST to a Home Assistant webhook URL you provide.
  • Pull (Home Assistant -> OpenMTG): Home Assistant fetches your live collection stats from OpenMTG on its own schedule, authenticated with a bearer secret.

Each webhook credential you create pairs both: a generated inbound URL + secret (for pull), and a field for your own Home Assistant target URL (for push).


Enabling the Integration

An admin must turn this on first in OpenMTG.

  1. Go to Admin > Settings > Feature Toggles.
  2. Toggle Home Assistant Integration on.
  3. Set Max webhook credentials per user (default 3).

When disabled: the Webhooks nav link is hidden for everyone, creating new credentials and sending test events is blocked, and the pull endpoint returns 503. Existing credentials stay visible and manageable.


Creating a Webhook Credential

Every OpenMTG user, including admins, manages their own credentials with no cross-user visibility.

  1. Go to Webhooks in the sidebar.
  2. Click New Credential.
  3. Give it a label (e.g. "Living Room HA").
  4. Optionally paste a Home Assistant webhook URL as the target URL. This URL is where push events go. Leave it blank for a pull-only credential.
  5. If that target URL is https:// with a self-signed certificate or an internal CA, check Skip TLS certificate verification.
  6. Click Create.

A one-time modal shows the generated inbound URL and bearer secret. Copy both now as only a hash of the secret is stored, and can never be displayed again. If you lose it, regenerate a new one from the credential's row. This keeps the same inbound URL and only rotates the secret.


Push Events (OpenMTG -> Home Assistant)

Every event POSTs JSON to the credential's target URL:

{
  "event": "trade_accepted",
  "timestamp": "2026-09-12T18:04:21.123Z",
  "trade_id": 25,
  "initiator": "tony",
  "counterpart": "alice"
}
Event Fires when Extra fields
trade_proposed A trade is proposed trade_id, initiator, counterpart
trade_updated Either side edits their offered items trade_id, initiator, counterpart
trade_engaged Trade moves from proposed to active (counterpart adds their first items) trade_id, initiator, counterpart
trade_accepted Both sides confirm and the transfer executes trade_id, initiator, counterpart
trade_rejected / trade_cancelled Trade closed without completing trade_id, initiator, counterpart
wishlist_target_met A wishlisted card's live price drops to or below your target_price, checked right after a price refresh card_name, set_code, set_name, foil, target_price, current_price, currency
test You clicked Send Test Event on a credential label

Trade events can push to both participants' credentials, each trader can point their own credential at their own Home Assistant instance. Wishlist events push only to the entry owner.

wishlist_target_met fires once per crossing. It won't repeat on every refresh while the price stays at or below target, but it re-arms if the price rises back above target and later drops again, or if you edit the target price, foil flag, or swap the tracked card.

Setting up the Home Assistant side

  1. In Home Assistant: Settings > Automations & Scenes > Create Automation.
  2. Add a trigger of type Webhook. Home Assistant generates a Webhook ID; the full URL is http://<your-ha-host>:8123/api/webhook/<that-id>.
  3. Paste that URL as the target URL on your OpenMTG credential.
  4. Add an action that uses the payload, e.g. a templated Persistent Notification:
action:
  - action: persistent_notification.create
    data:
      title: "OpenMTG"
      message: "{{ trigger.json.event }} - {{ trigger.json }}"
  1. Save, then click Send Test Event on the OpenMTG credential to confirm it fires.

To branch on event type, use a choose: block with a condition: template checking trigger.json.event.


Pull Endpoint - Collection Stats (Home Assistant -> OpenMTG)

GET /api/webhook/<username>/<webhook_id>/stats
Authorization: Bearer <secret>

Returns the same JSON shape as the in-app Stats page (summary, rarity, colors, color_identity_pct, types, conditions, top_cards, top_sets) for whichever user owns the credential. Rate-limited to 30 requests/minute per IP address.

Add it as a Home Assistant REST sensor in configuration.yaml:

rest:
  - resource: "http://<your-openmtg-host>:8080/api/webhook/<username>/<webhook_id>/stats"
    headers:
      Authorization: "Bearer <secret>"
    scan_interval: 300
    sensor:
      - name: "OpenMTG Total Value"
        value_template: "{{ value_json.summary.total_value }}"
      - name: "OpenMTG Total Cards"
        value_template: "{{ value_json.summary.total_cards }}"

Reload with Developer Tools > YAML > Reload REST (no full restart needed), then check Developer Tools > States for the new sensors. This is a separate config surface from the Lovelace dashboard The rest: block only creates the entities, dashboard cards reference them by entity id afterward.

REST sensors poll on scan_interval. See the dashboard example below for a manual refresh button using homeassistant.update_entity.


TLS and Self-Signed Certificates

Each credential has its own verify_tls flag, on by default. If the Home Assistant target URL is https:// with a certificate that isn't from a public CA (self-signed, or issued by an internal/private CA such as a reverse proxy's own root), OpenMTG's outbound push fails with a certificate verification error:

[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate

Fix it by toggling Skip TLS certificate verification either at credential creation or afterward via the shield icon next to the credential in the Webhooks list. Credentials without verification show a red Insecure badge next to their target URL as a standing reminder.

Only disable this for a URL on your own trusted network. It has no effect on the pull direction, Home Assistant calling into OpenMTG is authenticated by the bearer secret regardless of TLS settings on either side.


Managing Credentials

From the Webhooks page, each credential row supports:

Action Effect
Send test event Fires a test event to the target URL, if one is set
Shield icon Toggles TLS verification for that credential
Enable/disable toggle Disabling stops all push and pull traffic for that credential without deleting it
Regenerate secret Issues a new secret (shown once), keeps the same inbound URL
Delete Permanently removes the credential, any Home Assistant automation or sensor using it stops working

Example: Trade Notifier and Stats Dashboard

Trade notifier

  1. Create a Text helper: Settings > Devices & Services > Helpers > Create Helper > Text, named OpenMTG Last Trade (input_text.openmtg_last_trade).
  2. In the webhook automation, branch on event type and populate it:
action:
  - choose:
      - conditions:
          - condition: template
            value_template: "{{ trigger.json.event.startswith('trade_') }}"
        sequence:
          - action: input_text.set_value
            target:
              entity_id: input_text.openmtg_last_trade
            data:
              value: >-
                {{ trigger.json.event }}: {{ trigger.json.initiator }} ↔ {{ trigger.json.counterpart }}
          - action: persistent_notification.create
            data:
              title: "OpenMTG Trade Update"
              message: "{{ trigger.json.event }} — {{ trigger.json.initiator }} ↔ {{ trigger.json.counterpart }}"
              notification_id: "openmtg_trade_{{ trigger.json.trade_id }}"

Reusing notification_id keyed on trade_id means a trade's later events (updated, engaged, accepted) replace the same notification instead of piling up separate ones.

  1. Add a dashboard card:
type: tile
entity: input_text.openmtg_last_trade
name: Latest OpenMTG Trade

Stats card with manual refresh

type: vertical-stack
cards:
  - type: tile
    entity: sensor.openmtg_total_cards
    name: Total Cards
  - type: tile
    entity: sensor.openmtg_total_value
    name: Total Value
  - type: button
    name: Refresh Stats
    icon: mdi:refresh
    tap_action:
      action: perform-action
      perform_action: homeassistant.update_entity
      target:
        entity_id:
          - sensor.openmtg_total_cards
          - sensor.openmtg_total_value

Add either card via Edit Dashboard > Add Card > Manual (paste the YAML directly), or the dashboard's raw YAML editor. If you're on one of Home Assistant's default auto-generated dashboards, you may need Take Control first (dashboard's three-dot menu) before cards can be added.

For a true "refresh the instant the dashboard loads" behavior with no tap needed, you'd need the third-party browser_mod integration (via HACS), not required for anything above.


Troubleshooting

  • SSL: CERTIFICATE_VERIFY_FAILED, "unable to get local issuer certificate" - your target URL uses a self-signed or internally-issued certificate. Enable Skip TLS certificate verification on that credential.
  • curl or the REST sensor returns 404: Not Found - double-check the host and port. /api/webhook/... exists on OpenMTG, not Home Assistant. It's an easy mistake to point the pull request at your Home Assistant instance's own address (e.g. :8123) instead of OpenMTG's (:8080 by default).
  • Sensor state is unknown - the REST fetch likely succeeded but the response didn't have the field the value_template expects. Curl the same URL directly to see the raw JSON. A bare {} response means that user's collection is empty (same as the in-app Stats page showing "No collection data yet") - the summary key only appears once there's at least one card.
  • 401 Unauthorized from the pull endpoint - the bearer secret is wrong or was regenerated since the sensor was configured. Update the Authorization header with the current secret.
  • 503 from the pull endpoint - an admin has disabled the integration.
  • Push event never arrives in Home Assistant - confirm the credential is enabled, has a target URL set, and that the automation's webhook trigger URL matches exactly. Use Send Test Event to isolate whether the problem is OpenMTG-side or the automation itself.

API Reference

Method Path Description
GET /webhooks/status Public, integration enabled status and per-user credential cap
GET /webhooks List your own credentials
POST /webhooks Create a credential, response includes the secret and inbound URL once
PATCH /webhooks/{id} Update label, target URL, enabled, or verify_tls
DELETE /webhooks/{id} Remove a credential
POST /webhooks/{id}/regenerate-secret Rotate the secret, keeps the same inbound URL
POST /webhooks/{id}/test Send a test push event
GET /api/webhook/{username}/{webhook_id}/stats Pull endpoint, bearer-authenticated, not a normal session endpoint

All /webhooks/* endpoints except /webhooks/status require a normal login session and are scoped to the current user. The pull endpoint uses the credential's bearer secret instead and ignores session auth entirely.

Clone this wiki locally