Skip to main content

ButterflyMX Intercom

Cloud-managed multi-tenant video intercom. ButterflyMX is the dominant smart-intercom platform in modern apartment and mixed-use construction in North America; this driver brings their door-release and access-event API into GEM so a property's lobby / package-room / amenity doors can be triggered from macros, scenes, and access workflows.

What this integration covers

  • Door release ("buzz in") from a GEM macro or zone command — drives the BMX cloud's open endpoint for any door tied to your partner credentials.
  • Door roster polling — pulls the list of doors visible to the API key on a configurable cadence and reflects them as GEM zones.
  • Access event tail — walks the recent access-log feed and surfaces last-event metadata (event type, timestamp, who released) onto each door zone.
  • Building scoping — if your partner credentials span multiple properties, the optional building_id attribute scopes a single GEM device row to one building.

What this integration does NOT cover

  • SIP audio / video preview of a panel call. ButterflyMX panels speak SIP through their own iOS/Android/web clients; integrating that path requires a SIP UA stack and is out of scope here.
  • Resident / tenant provisioning (creating user accounts, mailing PINs, mailing physical keys). The BMX OS admin portal is the right tool for that.
  • Door schedule editing (auto-unlock windows). The driver reads scheduling state via get_doors but does not write to it.

Prerequisites

  • A ButterflyMX partner-tier account with API access enabled. Resident / front-desk credentials do not have API scope — contact your ButterflyMX rep.
  • A client_id and client_secret pair minted in the BMX partner portal.
  • Outbound HTTPS reachability from the GEM controller to:
    • accounts.butterflymx.com (OAuth 2.0 token endpoint)
    • api.butterflymx.com (REST API)

Setup steps

  1. Have your ButterflyMX partner contact provision API access for the property and mint a client_id + client_secret pair.
  2. In GEM admin → Devices → New Device, pick ButterflyMX Intercom as the driver.
  3. Enter the client_id and client_secret on the device row (the secret is encrypted at rest).
  4. If your credentials span multiple buildings and you want this device row scoped to one, set building_id to the BMX building UUID. Leave blank to include every visible building.
  5. Save the device row. After ~10 seconds the device should show as connected.
  6. From the Commands tab, run get_doors to enumerate available doors. Each entry's id is what you'll use as the zone address.
  7. Create a zone per door you want to control (zone subsystem gate or door makes the most sense; door is the default mapping). zone.address = the door's BMX UUID.

Attribute reference

Device attributes

NameTypeRequiredDescription
client_idstringyesOAuth 2.0 client_id from the BMX partner portal.
client_secretstringyesOAuth 2.0 client_secret. Stored encrypted.
api_basestringnoOverride the BMX API root. Default https://api.butterflymx.com. Only set if BMX has directed you to a regional or staging endpoint.
token_urlstringnoOverride the OAuth2 token endpoint. Default https://accounts.butterflymx.com/oauth/token.
building_idstringnoBuilding UUID filter when the credentials span multiple properties.
status_intervalintnoDoor roster poll cadence in milliseconds (default 60000, minimum 15000).
events_intervalintnoAccess-event feed poll cadence in milliseconds (default 30000, 0 disables).
request_timeoutintnoPer-request timeout (default 15000 ms).

Zone attributes

NameTypeDescription
addressstringThe BMX door UUID (required).
released_state_msintHow long zone.state stays "released" after an unlock before clearing back to "idle". Does NOT change the strike duration — that's set on the door in the BMX portal. Default 5000 ms.
statestringMaintained by the driver. "idle" normally, "released" for released_state_ms after an unlock.
last_eventstringMost recent access event type for this door.
last_event_atstringISO timestamp of the most recent access event.
last_event_userstringDisplay name of the actor on the most recent access event, if BMX surfaced one.

Zone address format

Plain BMX door UUID, e.g. 5f3a1c2e-8b9d-4f7a-b6e2-1a2b3c4d5e6f. Get the list with the get_doors command after first connect.

Commands

CommandArgsNotes
unlockaddressRelease / open the door. Strike duration is set on the BMX side.
openaddressAlias for unlock.
get_buildingsList buildings visible to the credentials.
get_doorsList doors. Use this to populate zone addresses.
get_panelsList intercom panels (the hardware door stations).
get_statusForce a status tick and return the cached door roster.
get_eventsoptional sinceWalk the recent access-log feed.
refresh_tokenForce a fresh OAuth2 token (debug).

Known limitations

  • Strike duration is not configurable from GEM. ButterflyMX owns that — set it on the BMX side per door.
  • No long-held / always-unlocked state. Most BMX doors are momentary; if a door is configured for an extended hold via BMX's own schedule, the driver does not currently surface that as a distinct zone state (it'll just report idle between release events).
  • Unlock endpoint is partner-tier. ButterflyMX has versioned this path in the past. If unlock returns a 404 on a brand-new partner contract, confirm the current path with your ButterflyMX rep — the driver will continue to function for read-only polling regardless.
  • No SIP audio/video (see "What this integration does NOT cover").

Troubleshooting

  • token request failed: HTTP 401client_id or client_secret is wrong, or the partner account doesn't have API scope enabled. Re-mint the credentials in the BMX portal.
  • HTTP 403 on /v3/doors — credentials are valid but the partner account doesn't have door-read scope. Contact your BMX rep to widen the scope.
  • HTTP 404 on unlock — the BMX unlock endpoint changed shape for your contract tier. Open a ticket with BMX to confirm the current path; read-only polling will keep working in the meantime.
  • HTTP 429 — the cloud is rate-limiting. Increase status_interval and events_interval.
  • Zones never transition past idle — make sure zone.address matches a UUID from the get_doors output verbatim. Address fields in the BMX API are case-sensitive.
  • Device shows disconnected after a few hours — token refresh failed. Check that accounts.butterflymx.com is reachable from the GEM controller; the driver auto-refreshes ~5 minutes before token expiry.