MapsWidget API v1

Account Setup

Please register an enterprise account at https://www.beans.ai/enterprise-console. When creating an account you may use the invite code sent to you in a separate email.

Once the account exists, a Beans API key and secret are generated for you automatically. Keep these credentials confidential — you will need them in every integration below, passed together as the string "key:secret".

Integration Overview

The Beans.ai Web Widget works across ESRI JS APIs, Beans Canvas, Mapbox, and Google Maps. There are two ways to integrate it.

  1. Library.
    You code and host the web page that renders the widget. This is the right choice when the widget lives inside your own site and is embedded in an existing page, and it allows far more customization than the hosted iframe.
  2. Hosted by Beans.ai.
    You link to the widget hosted on beans.ai — embedded in your site as an iframe, opened as an external link, or shown inside your mobile app as a WebView — using URL query parameters to specify what to display.
Either way, the option vocabulary is the same one documented under API Reference below: the hosted pages accept base64-encoded addressOptions, navOptions, and displayOptions that mirror the library arguments exactly.

Companion Products

Two products sit alongside the widget and are documented separately. If either describes your situation, start there — each has its own setup and neither needs anything unusual from the options below.
Product Reach for it when What it gives you
MapsWidget
Location SDK
You are embedding the widget in a mobile app WebView (Android WebView or iOS WKWebView) and want the user marker, map pinning, and distances to work. Removes the second location permission prompt. Your app streams the position it already has permission for straight into the page, so the user is asked once, by you, in your own words. Drop-in files for Android, iOS, and the page — no build step, and no change to your map page: keep navOptions.userLocation = 'LIVE' exactly as documented below.
MapsWidget
for Power BI
Your data already lives in Power BI and you want to see it on the property rather than embed a map in a web page at all. A custom Power BI visual rendering the same real map — every building, unit polygon, parking spot and amenity, 2D or 3D — colored by whatever column you bind. Answers "which units are vacant" and "is the churn on one side of the property" that a pin-per-address map visual cannot. No render call to write.

Setup

Pick your renderer for the script tags, container div, and a minimal render call. Everything you can then configure is in the API Reference that follows.

ESRI Integration
Headers
      
<link
href="https://www.beans.ai/mapswidget/css/mapswidget-1.0.4.css"
rel="stylesheet"
/>
<link
href="https://js.arcgis.com/4.23/esri/themes/light/main.css"
rel="stylesheet"
/>
      
End of body
      
<script type="text/javascript"
src="https://js.arcgis.com/4.23/"
></script>
<script type="text/javascript"
src="https://www.beans.ai/mapswidget/js/mapswidget-1.0.4.js"
></script>
      
Container
      
<div id="beans-maps-1" style="width: 50vw; height: 60vh;"></div>
      
👉 Please ensure that the container div has a predefined height and width. If the size is calculated on the fly, that may lead to incorrect rendering.

Initializing
The following is an example of the code that must be added to the body right after the two js files above:

Basic Rendering
      
<script type="text/javascript">
var be = new BeansMap();
be.render(
  "beans-maps-1",
  "...beans api key:secret...",
  [
    {
      address: "3815 N 16th St, Phoenix, AZ",
      unit: "251"
    }
  ],
  // Nav Options,
  {},
  // Display Options
  {},
  // Callback Options
  {}
);
</script>
      
👉 Please ensure that you specify the Beans api key secret.

Customizing

Everything beyond this point — the address options object, onClickData, onClickContent, the full displayOptions catalog, callbackOptions, and add-on selection via clientOptions — is documented once, for all renderers, in the API Reference.

ESRI is the only renderer that draws the complete visual vocabulary. Options marked ESRI in the reference — and only those — work here:
  • 3D camera. camera, mobileCamera, initialTilt, initialHeading, initialZ, orbit and compass.
  • Immersive layers. showImmersive and friends — 3D trees, ribboned walkways and drives, ground cover, and animated water.
  • Real terrain. useGroundElevation, offsetGroundElevation, useRelativeToGround, and the overrideHeight* extrusion hooks.
  • Mode overlays. satelliteModeUnitShape, shadowModeUnitShape, immersiveModeUnitShape, neighborModeUnitShape, plus shadows and neighbors.
  • Map Reel®. animateUnit and the animate* family, with per-unit quotes and amenityVideos.
Options marked 2D in the reference — numbersConfig, backgroundImage, mapStyle, initialZoom — are ignored here; ESRI draws its own equivalents.

👉 To offer a flat 2D view alongside this one, set displayOptions.addExternal2DSupport: true. The widget builds a hidden Beans Canvas twin and wires the 2D/3D buttons for you.
Beans Canvas Integration
Headers
      
<link
href="https://www.beans.ai/mapswidget/css/mapswidget-1.0.4.css"
rel="stylesheet"
/>
      
End of body
      
<script type="text/javascript"
src="https://www.beans.ai/mapswidget/js/banvas.js"
></script>
<script type="text/javascript"
src="https://www.beans.ai/mapswidget/js/mapswidget-1.0.4.js"
></script>
      
Container
      
<div id="beans-maps-1" style="width: 50vw; height: 60vh;"></div>
      
👉 Please ensure that the container div has a predefined height and width. If the size is calculated on the fly, that may lead to incorrect rendering.

Initializing
The following is an example of the code that must be added to the body right after the two js files above:

Basic Rendering
      
<script type="text/javascript">
var be = new BeansMap();
be.render(
  "beans-maps-1",
  "...beans api key:secret...",
  [
    {
      address: "3815 N 16th St, Phoenix, AZ",
      unit: "251"
    }
  ],
  // Nav Options,
  {},
  // Display Options
  {},
  // Callback Options
  {}
);
</script>
      
👉 Please ensure that you specify the Beans api key secret.

Customizing

Everything beyond this point — the address options object, onClickData, onClickContent, the full displayOptions catalog, callbackOptions, and add-on selection via clientOptions — is documented once, for all renderers, in the API Reference.

Beans Canvas is a flat SVG renderer with no external map SDK, which makes it the fastest option to load and the one that works offline against a site plan. Options marked All and 2D in the reference apply. In particular:
  • Site-plan backdrop. backgroundImage georeferences your own rendered site plan under the map, and canvasBackground sets the surrounding fill.
  • Unit numbers. showNumbers plus the full numbersConfig control set.
  • Glyph scaling. iconSizeMultiplier and showIconOnSVGs.
Options marked ESRI — 3D camera, immersive layers, terrain elevation, shadows, neighbors, Map Reel® — have no effect here and are safely ignored.

👉 To offer a 3D view alongside this one, set displayOptions.addExternal3DSupport: true. The widget builds a hidden ESRI twin, loading the ArcGIS SDK on demand, and wires the 2D/3D buttons for you.
Google Maps Integration
Headers
        
<link
  href="https://www.beans.ai/mapswidget/css/mapswidget-1.0.4.css"
  rel="stylesheet"
/>
        
End of body
        
<script type="text/javascript"
  src="https://www.beans.ai/mapswidget/js/mapswidget-1.0.4.js"
></script>
<script async defer
  src="https://maps.googleapis.com/maps/api/js?key=...&callback=initMap"
></script>
        
👉 Please ensure that you specify as your Google Maps API key when adding the Google Maps library to your code. Container
        
<div id="beans-maps-1" style="width: 50vw; height: 60vh;"></div>
        
Initializing
The following is an example of the code that must be added to the body right after the two js files above:

Basic Rendering
        
<script type="text/javascript">
  function initMap() {
    var be = new BeansMap();
    be.render(
      "beans-maps-1",
      "...beans api key:secret...",
      [
        {
          address: "3815 N 16th St, Phoenix, AZ",
          unit: "251"
        }
      ],
      // Nav Options,
      {},
      // Display Options
      {},
      // Callback Options
      {}
    );
  }
</script>
        
👉 Please ensure that you specify the Beans api key secret in the arguments to the render method. 👉 Please ensure that your calls to the Beans widget are wrapped inside Google Maps’ callback function.

Customizing

Everything beyond this point — the address options object, onClickData, onClickContent, the full displayOptions catalog, callbackOptions, and add-on selection via clientOptions — is documented once, for all renderers, in the API Reference.

The Google renderer is flat: tilt is suppressed and markers are HTML overlays. Options marked All and 2D in the reference apply, plus a few that are Google-only:
  • minZoom — furthest the user can zoom out.
  • hideZoomControl, hideCameraControl, hideScaleControl.
  • showFancyNumbers — richer unit-number badges.
  • skipMapPadding — suppresses the fitted-bounds padding.
Tree and other point immersive features are not drawn on this renderer; polygons and roads are. Options marked ESRI have no effect and are safely ignored.

👉 To offer a 3D view alongside this one, set displayOptions.addExternal3DSupport: true. The widget builds a hidden ESRI twin, loading the ArcGIS SDK on demand, and wires the 2D/3D buttons for you.
Mapbox Integration
Headers
        
<link
  href="https://www.beans.ai/mapswidget/css/mapswidget-1.0.4.css"
  rel="stylesheet"
/>
<link
  href="https://api.tiles.mapbox.com/mapbox-gl-js/v2.9.1/mapbox-gl.css"
  rel="stylesheet"
/>
        
End of body
        
<script type="text/javascript"
  src="https://api.tiles.mapbox.com/mapbox-gl-js/v2.9.1/mapbox-gl.js"
></script>
<script type="text/javascript"
  src="https://www.beans.ai/mapswidget/js/mapswidget-1.0.4.js"
></script>
        
Container
        
<div id="beans-maps-1" style="width: 50vw; height: 60vh;"></div>
        
👉 Please ensure that the container div has a predefined height and width. If the size is calculated on the fly, that may lead to incorrect rendering.

Initializing
The following is an example of the code that must be added to the body right after the two js files above:

Basic Rendering
        
<script type="text/javascript">
  var be = new BeansMap();
  be.render(
    "beans-maps-1",
    "...beans api key:secret...",
    [
      {
        address: "3815 N 16th St, Phoenix, AZ",
        unit: "251"
      }
    ],
    // Nav Options,
    {},
    // Display Options
    {},
    // Callback Options
    {}
  );
</script>
        
👉 Please ensure that you specify the Beans api key secret.

Customizing

Everything beyond this point — the address options object, onClickData, onClickContent, the full displayOptions catalog, callbackOptions, and add-on selection via clientOptions — is documented once, for all renderers, in the API Reference.

The Mapbox renderer is flat — drag-rotate is disabled and markers are mapboxgl.Marker elements. Options marked All and 2D in the reference apply.

👉 The Mapbox provider is the least complete of the four and is not recommended for new integrations. Immersive layers, trees, 3D camera, shadows, and neighbors are all unavailable. Use ESRI for a full-featured 3D map or Beans Canvas for the fastest flat one.
Base Url
Mapbox Integration
https://www.beans.ai/mapswidget/mapbox.html
https://www.beans.ai/mapswidget/mapbox-with-nav.html
Google Integration
https://www.beans.ai/mapswidget/google.html
https://www.beans.ai/mapswidget/google-with-nav.html
Library-like Integration
Query parameters
Parameter Name Required Type
apiKeySecret yes String:String
addressOptions Yes base64 encoded String of address options from the library integration
navOptions No base64 encoded String of navigation options from the library integration
displayOptions No base64 encoded String of display options from the library integration
Example
Mapbox
      
https://www.beans.ai/mapswidget/mapbox.html
?addressOptions=Wwp7CiAgICAgICAgICBhZGRyZXNzOiAiMzEwMCBXIExha2UgU3QsIE1pbm5lYXBvbGlzLCBNTiIsCiAgICAgICAgICB1bml0OiAiMzM0IgogICAgICAgIH0KXQ==
&navOptions=ewogICAgICAgIHBsYXRmb3JtOiAiQVBQTEUiLAogICAgICAgIHVzZXJMb2NhdGlvbjogewogICAgICAgICAgbGF0OiAzNC4xNzc5LAogICAgICAgICAgbG5nOiAtMTEyLjUzMzMKICAgICAgICB9CiAgICAgIH0=
&displayOptions=ewogICAgICAgIGluaXRpYWxNYXA6ICJTVFJFRVQiLAogICAgICAgIHNob3dVbml0U2hhcGU6IHRydWUsCiAgICAgICAgc2hvd1BhdGg6IHRydWUsCiAgICAgICAgcGF0aDogWwogICAgICAgICAgJ0VOVFJBTkNFJywKICAgICAgICAgICdFTEVWQVRPUicsCiAgICAgICAgICAnVU5JVCcKICAgICAgICBdLAogICAgICAgIHNob3dEaXJlY3Rpb25zOiB0cnVlLAogICAgICAgIGluaXRpYWxQb3NpdGlvbjogewogICAgICAgICAgYWRkcmVzczogIjMxMDAgVyBMYWtlIFN0LCBNaW5uZWFwb2xpcywgTU4iCiAgICAgICAgfQogICAgICB9
&apiKeySecret=...beans api key:secret...
      
Parameterized Implementation (limited functionality)
Query parameters
Single Result
Parameter Name Required Type
apiKeySecret yes String:String
address Yes String
unit No String
entrance.text No String
elevation.text No String
parking.text No String
card No Boolean
links No Boolean
markers No String,String,...
additionalPoints No Double;Double;String|...†
userLocation No LIVE|Double,Double
initialMap No One of STREET or SATTELITE
platform No One of APPLE or GOOGLE
showDirections No Boolean
showUnitShape No Boolean
showBuildingShape No Boolean
showPath No Boolean
path No String,String...
†Pipe separated list of Semicolon separated triple of lat, lng, and PointType where PointType is one of SWIMMINGPOOL, CARWASH, TENNIS, LAUNDRY, OFFICE, CLUBHOUSE, BBQ, MAILROOM, PACKAGELOCKER, CYCLESTORAGE, GYM

Multiple Results
Parameter Name Required Type
apiKeySecret yes String:String
addressPoints Yes String;String;String;String;String|...‡
additionalPoints No Double;Double;String|...†
card No Boolean
links No Boolean
markers No String,String,...
userLocation No LIVE|Double,Double
initialMap No One of STREET or SATTELITE
platform No One of APPLE or GOOGLE
showDirections No Boolean
showUnitShape No Boolean
showBuildingShape No Boolean
showPath No Boolean
path No String,String...
‡Pipe separated list of Semicolon separated list of address, unit, entrance.text, elevation.text, and parking.text
†Pipe separated list of Semicolon separated triple of lat, lng, and PointType where PointType is one of SWIMMINGPOOL, CARWASH, TENNIS, LAUNDRY, OFFICE, CLUBHOUSE, BBQ, MAILROOM, PACKAGELOCKER, CYCLESTORAGE, GYM
Example
Mapbox
      
https://www.beans.ai/mapswidget/mapbox.html
?address=1200+Dale+Ave,+Mountain+View,+CA+94043
&unit=43
&entrance.text=9111
&elevation.text=Floor+3
&additionalPoints=33.63427078772915,-111.86407107998963,CARWASH
&apiKeySecret=...beans api key:secret...
      
Mapbox with Nav
      
https://www.beans.ai/mapswidget/mapbox-with-nav.html
?address=1200+Dale+Ave,+Mountain+View,+CA+94043
&unit=43
&entrance.text=9111
&elevation.text=Floor+3
&additionalPoints=33.63427078772915,-111.86407107998963,CARWASH
&apiKeySecret=...beans api key:secret...
&userLocation=37.450469700667234,-122.16778683875827
&platform=APPLE
      
Google
      
https://www.beans.ai/mapswidget/google.html
?address=1200+Dale+Ave,+Mountain+View,+CA+94043
&unit=43
&entrance.text=9111
&elevation.text=Floor+3
&additionalPoints=33.63427078772915,-111.86407107998963,CARWASH
&apiKeySecret=...beans api key:secret...
      
Google with Nav
      
https://www.beans.ai/mapswidget/google-with-nav.html
?address=1200+Dale+Ave,+Mountain+View,+CA+94043
&unit=43
&entrance.text=9111
&elevation.text=Floor+3
&additionalPoints=33.63427078772915,-111.86407107998963,CARWASH
&userLocation=37.450469700667234,-122.16778683875827
&platform=GOOGLE
&apiKeySecret=...beans api key:secret...
      

Demo Links

Renderer Live examples
Beans Canvas example-banvasinlinewith multiple units
ESRI example-esriinlinewith multiple unitsno 3Dmultiple, no 3D
Google example-googleinlinewith multiple unitsno 3Dmultiple, no 3D
Mapbox example-mapboxinlinewith multiple unitsno 3Dmultiple, no 3D

How To Read This

Everything below is the complete, provider-independent reference for BeansMap.prototype.render. It is the same for every renderer, which is why it lives here rather than being repeated under each tab in Setup above — those tabs cover only the script tags, container div, and minimal render call each renderer needs to boot.

The Providers column on every table below tells you where an option actually has an effect.

Value Meaning
All Handled by the shared widget layer. Works on ESRI, Beans Canvas, Google, and Mapbox, wherever the underlying UI exists.
ESRI Requires the ESRI/ArcGIS SceneView renderer — the 3D, immersive, and camera-orbit features. Silently ignored elsewhere.
2D Applies to the flat renderers: Beans Canvas, Google, and Mapbox. Ignored on ESRI, which draws its own 3D equivalent.
Canvas / Google / Mapbox Specific to that one renderer.
Every option is optional unless marked Required, and passing an unknown option is harmless. Options are read once at render() time; to change them, call render() again with displayOptions.forceRerender: true.

render() Signature

var be = new BeansMap();
be.render(
  containerDivId,     // String — id of the div to render into (must have a fixed width/height)
  apiKeySecret,       // String — "key:secret" from the Beans enterprise console
  addresses,          // Array  — one entry per unit / address to display
  navOptions,         // Object — user location + navigate button
  displayOptions,     // Object — everything about how the map looks and behaves
  callbackOptions,    // Object — event hooks back into your page
  clientOptions       // Object — add-on selection (parking, storage)
);
👉 The container div must have a resolved width and height before render() is called. If the size is computed later the widget waits on a ResizeObserver, but a zero-size container that never resizes will never draw.

Address Object

The third argument is an array of objects. Each entry is one selectable unit on the map. A property with 120 available units is 120 entries, all sharing the same address.

Field Type Description
address String Required. Street address of the property. Must be identical across all entries for one property.
unit String Unit identifier. Leave empty for an address-level pin. || joins a compound label and renders as " - ".
country String Country hint passed to geocoding. Useful for non-US addresses that would otherwise standardize incorrectly.
snap String Snapping hint forwarded to the search API when the unit must bind to a specific geometry.
options Object Per-unit display overrides. See the next section.
[
  {
    address: "1200 Dale Ave, Mountain View, CA",
    unit: "43",
    options: { /* ... */ }
  },
  {
    address: "1200 Dale Ave, Mountain View, CA",
    unit: "44",
    options: { /* ... */ }
  }
]

Per-Unit Options

Option Type Providers Description
onPreviewDataArrayAll Rows shown under the unit in the unit list, on hover, and inside the unit card. Each row is {value, title?, icon?}. See onPreviewData.
onPreviewTitleStringAll Overrides the title line of the hover popover. Without it the unit number is used.
onPreviewContentString (HTML)All Raw HTML for the hover popover. Takes priority over onPreviewData.
onClickDataObjectAll Structured unit data. Drives the unit card, floorplan grouping, filters, and the onSelect payload. See onClickData.
onClickContentString (HTML)All Raw HTML rendered in place of the Beans unit card. Takes priority over onClickData unless displayOptions.useBeansReplacingOnClickContent is set.
onCardContentString (HTML)All Raw HTML for this unit's row in the unit list. Legacy path — prefer onClickData plus onPreviewData, which the modern list renders natively.
unitShapeObjectAll Per-unit shape override, layered on top of the global displayOptions.unitShape. Same fields as shape objects.
tilesObjectAll Text and icon overrides for the tile strip in the Beans card. Keys: keybox, entrance, elevation, parking; each takes {text, iconUrl}. Requires displayOptions.showTiles.
markersObjectAll Map-marker overrides. See markers.
poiArrayAll Additional or suppressed points of interest for this unit. See poi.
quotesObjectESRI Map of amenity or POI type to a testimonial string, shown in the Map Reel® overlay as the camera passes that amenity. Keys are upper-cased types, e.g. {"SCHOOL": "...", "DOGPARK": "..."}.
amenityVideosObjectESRI Map of amenity or POI type to a video URL, played in the Map Reel® overlay. Same key convention as quotes.
repositionToAmenitiesBooleanESRI With the amenity dock active, re-frame the camera on the amenity set rather than the unit. Normally managed by the widget.
dontZoomToAmenitiesBooleanESRI Suppresses that re-framing for this unit.
Content precedence
Three surfaces can each be driven either by structured data or by an HTML blob. HTML always wins, with one deliberate exception.

Surface Structured HTML override
Hover popover onPreviewData / onPreviewTitle onPreviewContent
Unit card (on click) onClickData (+ onPreviewData fallbacks) onClickContent
Unit list row onClickData + onPreviewData onCardContent
The exception. displayOptions.useBeansReplacingOnClickContent = true makes the widget render its own unit card even when onClickContent is supplied. The blob is still mined for the values the structured card needs — rent, availability, floorplan code, floorplan image, and the CTA button or link — so a host that only has an HTML blob still gets the full Beans card. This is how the RealPage integration runs.

Fallback parsing. When onClickData is missing a field, the widget parses onPreviewData rows for it: bed / bath / sq ft out of strings like "3 Beds / 2.5 Baths / 1500 sq. ft.", rent out of "$3,200" or "From $890", floor out of "Floor 3", and the floorplan code from the first short row that is none of those. You do not have to duplicate data you already pass in onPreviewData, but structured onClickData is always more reliable.

onClickData

The structured description of one unit. Powers the unit card, the Floorplans tab grouping, the filters, and the payload passed to callbackOptions.onSelect and callbackOptions.onHover.

Field Type Where it shows
nameStringUnit identifier echoed back in callbacks.
floorplanStringPlan code, e.g. "A1". Renders as "PLAN A1" under the card title and groups units in the Floorplans tab.
bedNumber / StringBED stat tile. Drives the bed filter and selectableUnitShape.perBedroom coloring.
bathNumber / StringBATH stat tile. Drives the bath filter. Decimals supported.
sqftNumber / StringSQ FT stat tile. Drives the sqft filter.
floorNumber / StringFLOOR stat tile and the LOCATION info card. Falls back to the map's selected floor.
rentNumber / StringPrice block. A number formats as $3,200; a string passes through verbatim, so "From $890" works.
availabilityStringAvailability line and the AVAILABILITY info card. Falls back to status, then to a parsed "Available ..." row, then to "Available now".
statusStringAlternate availability source. Also usable as a status filter value.
floorplanImgString (URL)Floorplan image in the left column of the unit card. Click opens it full-screen.
imagesArrayGallery tiles, [{url: "..."}, ...]. Up to 4 render inline (3 when a tourLink takes a slot); clicking one opens the full set full-screen.
tourLinkString (URL)Adds a "3D TOUR" tile at the head of the gallery row. Opens in a new tab.
scheduleLinkString (URL)Renders the "Schedule Tour" button in the card footer. Only when explicitly set — it never falls back to link.
linkString (URL)Primary call to action, "Apply Now" by default. Opens in a new tab.
ctaLabelStringLabel for the CTA button. Falls back to displayOptions.applyStr, then to "Apply Now".
ctaHtmlString (HTML)Non-web CTA — your own <button>, or a tel: / mailto: anchor. The element is re-materialized and our button forwards clicks into it, so inline handlers run with the original element as this. Used only when link is absent.
onClickData: {
  name: "L101",
  floorplan: "A1",
  bed: 1,
  bath: 1,
  sqft: 1024,
  floor: 1,
  rent: 3200,
  availability: "Available Now",
  floorplanImg: "https://.../plan-a1.jpg",
  images: [
    {url: "https://.../photo-1.jpg"},
    {url: "https://.../photo-2.jpg"}
  ],
  tourLink: "https://.../3d-tour",
  scheduleLink: "https://.../schedule",
  link: "https://.../apply?unit=L101",
  ctaLabel: "Apply Now"
}

onPreviewData

An ordered array of rows. value is the text and may contain HTML, title is an optional label above it, and icon selects a built-in glyph. A value beginning with img: is skipped by the text renderer.

icon Glyph
bedBedrooms
bathBathrooms
sizeSquare footage
floorFloor
floorplan / matterportFloorplan
availabilityCalendar
priceRent
locationTeardrop pin
When icon is omitted the widget infers one from the text: "bath", "bed", "sqft" / "sqyd", "floor ".
onPreviewData: [
  { icon: "bed",          value: "3 Bed / 2 Bath / 1500 sq. ft." },
  { icon: "price",        value: "$3,200 / mo" },
  { icon: "availability", value: "Available Now" }
]

markers

Controls the pins drawn on the map for this unit. Keys are marker types in lower case — unit, entrance, elevator, stair, parking, keybox, plus any type present in the Beans data set for the property.

Field Type Description
displayBooleanAt the top level of markers, hides or shows every marker. Inside a type, overrides that one type against the global setting.
textStringLabel rendered on the marker.
iconUrlString (URL)Custom icon. Match the size and format of the reference icons.
colorCodeStringOverrides the marker fill color.
zIndexNumberStacking order. Defaults: unit 1005, entrance 1004, elevator 1003, stair 1002, parking 1001, everything else 1000.
divHTMLElement / String / FunctionFully custom marker DOM. Accepts a live element, an HTML string, or a zero-argument factory. Live elements are used as-is, so listeners you attached survive.
markers: {
  // Hide everything...
  display: false,

  // ...except the entrance, relabeled and re-iconed.
  entrance: {
    display: true,
    text: "#9111",
    iconUrl: "https://storage.googleapis.com/beans-mobile-resources/marker-note-icons/...",
    zIndex: 1200
  }
}

poi

Adds points of interest, or suppresses ones that come from the Beans data set.

Field Type Description
nameStringRequired. POI type. Use "ALL" with display: false to suppress every Beans POI.
location{lat, lng}Required when adding a new POI. Omit when suppressing an existing one.
displayBooleanSet to false to hide a Beans-provided POI of this type.
iconUrlString (URL)Custom icon.
colorCodeStringCustom marker color.
Built-in POI type names: SWIMMINGPOOL, CARWASH, TENNIS, LAUNDRY, OFFICE, CLUBHOUSE, BBQ, MAILROOM, PACKAGELOCKER, CYCLESTORAGE, GYM, DOGPARK, PLAYGROUND, TRASH, FREEFORM.

A custom marker whose name contains a colon, e.g. "POOL:101", has its full name passed as the first argument to onPOIClick, so you can route on the suffix.
poi: [
  {
    location: { lat: 33.63427, lng: -111.86407 },
    name: "CARWASH",
    iconUrl: "https://storage.googleapis.com/beans-mobile-resources/marker-note-icons/..."
  },
  { name: "TRASH", display: false }
]

navOptions

Option Type Providers Description
userLocation{lat, lng} / StringAll Where the user is. Pass a fixed {lat, lng}, or "LIVE" to use the browser's geolocation as a continuous watch, or "MANUAL" to accept positions you push in yourself. Required for the navigate button and for walking-path rendering. In a mobile WebView, see the Location SDK.
platformStringAll "APPLE" or "GOOGLE" — which maps app the navigate button opens. Defaults to Google.
hideNavigateButtonBooleanAll Hides the navigate button even when a user location is available.
hideMyLocationButtonBooleanAll Hides the "my location" button.

displayOptions — Base Map & Camera

Option Type Providers Description
initialMapStringAll"SATELLITE" or "STREET". Sets the basemap on load.
mapStyleString2DStyle id for the flat basemap.
initialPositionObjectAllWhere the map starts: {lat, lng}, or {address, country} which is standardized first.
initialZoomNumber2DStarting zoom level.
minZoomNumberGoogleMinimum zoom the user can pull out to.
initialTiltNumberESRI, GoogleCamera tilt in degrees; 0 looks straight down. Must be accompanied by initialPosition.
initialHeadingNumberESRI, GoogleCamera bearing in degrees; 0 is North.
initialZNumberESRICamera height in metres.
cameraObjectESRIFull camera in one object: {tilt, heading, position: {x, y, z}} where x/y are lng/lat. Preferred over the four initial* fields, and overrides them.
mobileCameraObjectESRIUsed instead of camera when the widget renders in its mobile layout.
restrictToBoundsBooleanAllPrevents panning outside the property extent.
showPropertyExtentBooleanAllFrames the whole property boundary on load rather than a single unit.
disableRepositionBooleanAllStops the widget re-framing the camera after data loads. Use with an explicit camera.
useGroundElevationBooleanESRIPlaces the scene on real terrain elevation instead of a flat plane.
offsetGroundElevationNumberESRIMetres to lift the building base by. Required when useGroundElevation is on.
useRelativeToGroundBooleanESRISwitches shape elevation from absolute-height to relative-to-ground.
backgroundImageObject2DGeoreferenced site-plan image drawn under the map: {src, position: {lat, lng, lat2, lng2}}, the two corners being opposite ends of the image. Setting it also forces a plain basemap and zoom 19.
ignoreBackgroundBoundsBoolean2DKeeps the background image from contributing to the map's fitted bounds.
skip2DBackgroundBooleanAllSuppresses the automatic 2D backdrop when no background image is configured.
canvasBackgroundStringCanvasBackground fill for the Beans Canvas renderer.

displayOptions — Buttons & Chrome

Option Type Providers Description
modernButtonsBooleanAllLarger labelled buttons instead of icon circles.
outsideButtonsBooleanAllMoves the button bar outside the map surface. On mobile this also changes the card layout.
enableBurgerButtonBooleanAllCollapses secondary buttons behind a burger menu.
hideSatelliteButtonBooleanAllHides the satellite / street toggle.
hideShadowBooleanESRIHides the sun-shadow toggle.
isShadowEnabledOnLoadBooleanESRIStarts with shadows on.
shadowOnLoadTsStringESRIDate/time parseable by Date.parse for the initial sun position.
isSatelliteEnabledOnLoadBooleanESRIStarts in the satellite basemap.
isNearbyEnabledOnLoadBooleanESRIStarts with the Nearby sheet open.
hideRotateControlBooleanESRI, GoogleHides the rotate control. See the caveat below.
hideZoomControlBooleanGoogleHides the zoom control.
hideCameraControlBooleanGoogleHides the camera / tilt control.
hideScaleControlBooleanGoogleHides the scale bar.
showCompassBooleanESRIShows the ArcGIS compass widget.
showZoomToUnitBooleanESRIAdds a button that re-frames on the selected unit.
showShareButtonBooleanAllAdds a share button. Fires onShareButtonClick.
showHelpButtonBooleanAllAdds a help button. Fires onHelpButtonClick.
showCloseButtonBooleanAllAdds a close button to the widget chrome.
showPOIButtonBooleanAllShows the nearby-POI toggle and the Nearby sheet.
hidePOIsCardBooleanAllKeeps the POI button but suppresses the sliding POI card.
show2DButtonBooleanAllShows a "2D map" button.
event2DFunctionAllHandler for the 2D button. Takes precedence over href2D.
href2DStringAllURL fragment swapped into the current location when the 2D button is clicked.
show3DButtonBooleanAllShows a "3D map" button.
event3DFunctionAllHandler for the 3D button. Takes precedence over href3D.
href3DStringAllURL fragment swapped in when the 3D button is clicked.
addExternal2DSupportBooleanESRIBuilds a hidden second widget on the Beans Canvas renderer and wires the 2D/3D buttons to swap between them. No extra markup required.
addExternal3DSupportBoolean2DThe mirror image: builds a hidden ESRI widget alongside a flat one, loading the ArcGIS SDK on demand if it is not already present.
showFullScreenModeBooleanAllAdds the full-screen toggle.
isFullScreenModeBooleanAllStarts in full-screen.
fullScreenTopPaddingString (CSS)AllPadding reserved at the top in full-screen, e.g. "50px", for a host header.
fullScreenBottomPaddingString (CSS)AllThe same at the bottom.
colorsObjectAllBrand colors applied as CSS custom properties: {beansColor1, beansColor2, beansTextColor1}.
customDivsObjectAllHost-supplied DOM injected into the widget. {header: HTMLElement} is prepended to the Beans card. With addExternal2DSupport, {d2: {...}} supplies a separate set for the 2D twin.
iconSizeMultiplierNumberCanvasScales marker and label glyphs.
⚠️ On ESRI, hideRotateControl: true suppresses the whole 3D button cluster, not just the rotate control: the shadow, zoom-to-unit, neighbors, amenity-mode, and immersive buttons all sit behind the same guard. To keep those buttons but lose rotation, leave hideRotateControl unset.

displayOptions — Cards

Option Type Providers Description
hideBeansCardBooleanAllHides the info card entirely.
modernBeansCardBooleanAllEdge-to-edge card instead of one floating inside the map.
hideBeansCardOnFullScreenModeBooleanAllHides the card only while full-screen.
mobileBeansCardSizeNumberAllHeight in px of the mobile card. Default 260.
hideAddressBooleanAllSuppresses the address line in the card.
propertyAddressStringAllProperty address used for standardization and card display when it differs from the first entry's address.
preferredWordStringAllNoun used instead of "Unit" throughout the UI, e.g. "Suite" or "Home".
showWideUnitCardBooleanAllTwo-column desktop unit card instead of the stacked layout. Currently pinned on — see the note below.
inlineClickDataBooleanAllRenders unit details inside the Beans card instead of a popup. Currently pinned off — see the note below.
hoverMinWidthNumberAllMinimum width in px of the hover popover.
hideFloorInPreviewBooleanAllOmits the floor row from hover previews.
applyStrStringAllLabel for the primary CTA button. Default "Apply Now".
scheduleStrStringAllLabel for the schedule button. Default "Schedule Tour".
skipDisclaimerTextBooleanAllSuppresses the pricing disclaimer under rent figures.
useBeansReplacingOnClickContentBooleanAllRender the Beans unit card even when onClickContent is supplied, mining the blob for values. See content precedence.
showTilesBooleanAllShows the unit / entrance / elevator tile strip.
showLinksBooleanAllShows the distance links row.
showDirectionsBooleanAllShows turn-by-turn directions in the card.
showSeparateFacilitiesCardBooleanAllMoves the facilities index into its own bottom bar.
showClickableFacilitiesTitleBooleanAllMakes the facilities bar title interactive.
pricingObjectAllFee schedule for the pricing-transparency calculator inside the unit card. See pricing.
⚠️ Four options are currently pinned by the library and ignore whatever you pass. In the shipped 1.0.4 build, render() forces showWideUnitCard = true, inlineClickData = false, animateUnit = false, and disableAutoSelectOnFloor = true before anything else runs. They are documented here because they are part of the intended API and the pin is expected to be lifted; until then, setting them has no effect. Talk to your account manager if you need one of these behaviors today.

displayOptions — Unit List & Filters

Option Type Providers Description
showUnitListBooleanAllShows the multi-unit selector.
unitListTitleStringAllText after the count in the list header. Default "units available".
noUnitsContentString (HTML)AllHTML shown when the list is empty, whether there are no units or everything was filtered out.
hideFloorplansTabBooleanAllRemoves the Floorplans tab, leaving only the flat unit list.
skipFirstSelectBooleanAllOpens with nothing selected instead of auto-selecting the first unit.
skipScrollingBooleanAllStops the list auto-scrolling to the selected unit.
hideFiltersBooleanAllHides the filter row.
forceHideFiltersBooleanAllHides filters including the mobile filter button.
modernFiltersBooleanAllModern filter chips. On by default unless standaloneFilters is set.
standaloneFiltersBooleanAllRenders filters as a detached block rather than inside the list header.
filtersObjectAllReplaces the default filter set. See filters.

displayOptions — Shapes

Option Type Providers Description
showUnitShapeBooleanAllDraws unit outlines.
unitShapeObjectAllBase style for every unit.
mobileUnitShapeObjectAllReplaces unitShape in the mobile layout.
selectedUnitShapeObjectAllStyle for the currently selected unit.
selectableUnitShapeObjectAllStyle for units that can be selected. Accepts an extra perBedroom map, {0: {...}, 1: {...}, 2: {...}} keyed on onClickData.bed, to color units by bedroom count.
selectedUnitShapeSameFloorObjectAllStyle for other units on the selected unit's floor.
hoverUnitShapeObjectAllStyle applied while the pointer is over a unit.
satelliteModeUnitShapeObjectESRIOverlay merged in while the satellite basemap is active.
shadowModeUnitShapeObjectESRIOverlay merged in while shadows are on.
immersiveModeUnitShapeObjectESRIOverlay merged in while the immersive layers are visible.
neighborModeUnitShapeObjectESRIOverlay merged in while neighboring buildings are shown.
unitShapeConfig{convert}AllPer-unit style function, convert(description, style) returning a style. Called for every polygon.
colorsConfigFunctionESRIcolorsConfig(description) returning a color config. Assigns colors to non-unit polygons by description.
unitsToExcludeArray<String>AllSubstrings; any polygon whose description contains one is not drawn.
overrideShapesObjectAllPer-unit geometry override keyed by unit string: {"43": {baseHeight, wallHeight}}. Heights in metres.
overrideHeightNumberESRIFixed wall height in metres for every unit.
overrideHeightFnFunctionESRI(description, height) returning a height. Takes precedence over overrideHeight.
overrideBaseHeightFnFunctionESRI(description, baseHeight) returning a base height. Controls the floor a unit sits on.
showBuildingShapeBooleanAllDraws the building outline.
showBuildingShape2DBoolean2DThe same, for the flat renderers only.
showAllBuildingShapesBooleanAllDraws every building on the property, not just the selected unit's.
showAllBuildingShapes2DBoolean2DThe same, flat renderers only.
buildingShapeObjectAllStyle for building outlines.
showNeighborsBooleanESRIEnables the neighboring-buildings toggle.
neighborShapeObjectESRIStyle for neighboring buildings.
poiShapeObjectAllStyling for amenity and POI polygons: {fillOpacity}, or {colorCodes: [{value, color}, ...]} to replace the whole palette.
showSingleFamilyBooleanESRIRenders single-family geometry in addition to multifamily.
showUndergroundBooleanESRIDraws below-grade levels.
fastBuildingUnitPolygonsString (URL)AllPre-baked polygon payload fetched instead of assembling geometry from the API. A load-time optimization for large properties.

displayOptions — Numbers & Markers

Option Type Providers Description
showNumbersBooleanAllDraws unit numbers on the map.
numbersConfigObject2DFull control over how those numbers render. See numbersConfig.
showFancyNumbersBooleanGoogleRicher number badges.
showParkingNumbersBooleanAllDraws numbers on parking and storage elements.
showIconOnSVGsBooleanCanvasAmenity shapes render an icon instead of the lettering baked into the SVG.
markerShapeStringAll"circle" for round markers; omit for the default teardrop.
hideUnitMarkerBooleanAllSuppresses the pin on the selected unit.
alwaysShowUnitMarkersBooleanAllKeeps unit pins visible even when unit shapes and the list are both on.
showFloorOnUnitMarkerBooleanAllLabels unit pins with their floor.
showCodeOnUnitMarkerBooleanAllLabels unit pins with their code.
restrictMarkersToPathBooleanAllOnly draws markers the computed walking path actually uses.
multiModalBooleanAllKeeps both unit shapes and unit markers active together.

displayOptions — Floors

Option Type Providers Description
hideFloorSelectorBooleanAllHides the floor list.
selectedFloorNumber / StringAllFloor selected on load.
selectedFloor2DNumber / String2DInitial floor for the flat renderers, applied once and then released.
disableAutoSelectOnFloorBooleanAllChanging the floor no longer auto-selects a unit on it. Currently pinned on — see the Cards note.
showFloorSliderBooleanAllVertical slider instead of a floor list. Desktop only.
showFloorRollerBooleanAllScroll-wheel floor roller. Desktop only, and overrides the slider.
showHighriseFloorPickerBooleanAllInteractive stacked-floor diagram for towers. The viewer plugin is loaded on demand.
floorDesignObjectAllConfig for the high-rise picker. Required alongside showHighriseFloorPicker.
highriseFloorPickerDockStringAll"left" or "right" (default).
showFloorSelectorForParkingBooleanAllKeeps the floor selector active in parking or storage mode.

displayOptions — Wayfinding Path

Option Type Providers Description
showPathBooleanAllDraws the navigation path.
showClickablePathBooleanAllMakes path waypoints clickable without drawing the full path.
pathArray<String>AllOrdered waypoint sequence. Default ['PARKING','ENTRANCE','ELEVATOR','STAIR','UNIT']. Steps whose markers are absent are dropped automatically. Also accepts 'CURRENTLOCATION', 'PARKING_OR_CURRENTLOCATION', a 'LATLNG...' literal, and a 'DRIVING && ' prefix to force a driving leg.
snapToLinesBooleanAllSnaps the drawn path to the property's walkway centerlines.
animatePathBoolean2DAnimates a pulse along the path.
animatePathLoopIntervalNumber2DMilliseconds per animation loop.

displayOptions — Immersive Layers

Option Type Providers Description
showImmersiveBooleanESRIEnables the immersive toggle — 3D trees, walkways, drives, lawn, mulch, and animated water.
showImmersiveOnLoadBooleanESRIStarts with the immersive layers already on.
showImmersiveLightBooleanESRIReduced immersive set for faster first paint.
showImmersiveBalloonsBooleanESRIFloating labels above immersive features. On by default; set false to suppress.
immersiveConfigArrayESRIReplaces the default immersive catalog. Each entry is an ArcGIS feature-layer spec with a url, a renderer, elevationInfo, and an immersiveType label. The defaults cover trees, walk and drive surfaces, ground cover, and water.
immersiveUnitsString (URL)ESRIFeature-service URL for a property-specific immersive unit layer, appended to immersiveConfig.

displayOptions — Amenities & Nearby

Option Type Providers Description
communityAmenitiesArrayAllRich amenity definitions. Adds a "Community amenities" block to the unit card, makes dock chips fly the camera to the amenity, and gives amenity pins a photo and description hover card. See communityAmenities.
renameAmenitiesFunctionESRI(description) returning a label. Relabels amenity polygons at draw time.
showAmenityModeBooleanESRIEnables the amenity-first browsing mode.
amenityPopupHeightNumberESRICallout height in screen px for amenity popups. Defaults to 70, or 30 on mobile.
syntheticAmenityContentBooleanAllFabricates placeholder copy and photos for amenities that have no configured content. Off by default — without it, unconfigured amenities render a minimal card rather than invented text.
poiOptionsArrayAllReplaces the Nearby category list. See poiOptions.
proximityRadiusMNumberAllRadius in metres for onProximityChange. Default 50.

displayOptions — Map Reel®

Option Type Providers Description
animateUnitBooleanESRIAdds the Map Reel® button to the unit card. Clicking it plays a scripted camera move around the selected unit and its surroundings. Currently pinned off — see the Cards note.
animateOnLoadBooleanESRIPlays the reel automatically once the map is ready.
animateUnitAxisModeStringESRIRotation axis for the orbit phase. Default "global".
animateNearbyCategoryStringESRIPOI category the reel flies out to, matched against poiOptions[].type / .value. Defaults to the first configured category.
animateNearbyAsArcBooleanESRIFlies to the nearby POI along an arc. Set false to follow the routed path instead.
perspectiveStepNumberAllFraction of the scene span used per perspective step. Default 0.003.
Per-unit quotes and amenityVideos supply the copy and video that play as the reel passes each amenity — see Per-Unit Options.

displayOptions — Add-Ons

Option Type Providers Description
parkingShapeObjectAllBase style for add-on elements.
selectableParkingShapeObjectAllStyle for available add-ons. Accepts byNamePrefix, a map of category name to {text, fillColor, fillOpacity}, which also drives the add-on filter legend.
selectedParkingShapeObjectAllStyle for the chosen add-on.
allowParkingUnselectBooleanAllLets the user deselect an add-on they had picked. Fires onUnselect.
skipParkingConfirmationBooleanAllFires onSelect immediately instead of showing the Confirm / Cancel panel.
The elements themselves are supplied through clientOptions.

displayOptions — Rendering & Lifecycle

Option Type Providers Description
beansMapTypeStringAllForces the renderer: "ESRI", "BANVAS" (Beans Canvas), "GOOGLE", or "MAPBOX". Without it the widget picks whichever SDK is present, in that priority order.
forceRerenderBooleanAllRequired to make a second render() rebuild the map. Without it, a repeat call with the same addresses is treated as a filter change and only re-styles what is already drawn.
initialUnitStringESRIUnit selected on load, matched against the geocoded unit rather than array position. Cleared once applied.
highlightOptionsObjectESRIArcGIS SceneView highlight styling: {color: [r,g,b,a], haloOpacity, fillOpacity}.
hideEEBooleanAllSuppresses the easter-egg surface.

Shape Objects

Every *Shape option takes the same fields, and merges onto the built-in defaults — so you only specify what you want to change.

Field Type Description
fillColorStringHex fill.
fillOpacityNumber 0–1Fill opacity.
strokeColorStringHex outline.
strokeOpacityNumber 0–1Outline opacity.
strokeWeightNumberOutline width.
fillColorOnShadowMode
fillOpacityOnShadowMode
String / NumberValues swapped in while shadows are on.
fillColorOnNeighborMode
fillOpacityOnNeighborMode
String / NumberValues swapped in while neighbors are shown.
Defaults
unitShape:              { fillColor: '#ffffff', fillOpacity: 0.7, strokeWeight: 0.25,
                          strokeOpacity: 1, strokeColor: '#000000',
                          fillColorOnShadowMode: '#cdeefd', fillOpacityOnShadowMode: 1.0 }
selectedUnitShape:      { fillColor: '#cc088e', fillOpacity: 1.0, strokeWeight: 1.0,
                          strokeOpacity: 1.0, strokeColor: '#ffffff' }
selectableUnitShape:    { fillColor: '#24453E', fillOpacity: 1.0, strokeWeight: 1.0,
                          strokeOpacity: 1.0, strokeColor: '#ffffff' }
neighborShape:          { fillColor: '#ffffff', fillOpacity: 0.2, strokeWeight: 1.0,
                          strokeOpacity: 1.0, strokeColor: '#000000' }
parkingShape:           { fillColor: '#c5c5c5', fillOpacity: 1.0, strokeWeight: 1,
                          strokeOpacity: 1.0, strokeColor: '#ffffff' }
selectableParkingShape: { fillColor: '#0cb1a1', fillOpacity: 1.0, strokeWeight: 1.0,
                          strokeOpacity: 1.0, strokeColor: '#ffffff' }

// Mode overlays — merged on top of the resolved unit shape while active
shadowModeUnitShape:    { fillOpacity: 1.0 }
satelliteModeUnitShape: { fillOpacity: 1.0 }
immersiveModeUnitShape: { fillOpacity: 0.9 }
Resolution order for a given unit, later winning:

default → displayOptions.unitShape → state shape (selectableUnitShape / selectedUnitShapeSameFloor / selectedUnitShape) → per-unit options.unitShape → active mode overlay (satellite / shadow / immersive / neighbor) → hoverUnitShape.

numbersConfig

Controls the unit-number labels drawn on the flat renderers. Every *Fn variant takes precedence over its static counterpart and is called as fn(description, rawDescription, purpose).

Field Type Description
convertFunction(unitString) returning a label. Rewrites the text before it is drawn — strip prefixes, drop hyphens, shorten. Also used for hover titles.
size / sizeFnString / FunctionFont size, e.g. "10px".
color / colorFnString / FunctionText color.
backgroundColorStringBadge background.
borderString (CSS)Badge border, e.g. "1px solid black".
textShadow / textShadowFnString / FunctionCSS text shadow.
xOffset / xOffsetFnNumber / FunctionHorizontal nudge in px.
yOffset / yOffsetFnNumber / FunctionVertical nudge in px.
rotate / rotateFnNumber / FunctionRotation in degrees.
minZoom / getMinZoomNumber / FunctionZoom below which the label is hidden. getMinZoom(unitString) allows a per-unit threshold.
iconSizeNumberSize of the icon rendered alongside the number.
resizeNumbersBooleanScales labels with zoom instead of holding a constant screen size.
hideNumbersOutsideViewBooleanSkips labels whose anchor is off-screen.
showNumbers: true,
numbersConfig: {
  backgroundColor: '#FFFFFF',
  border: '1px solid black',
  size: '10px',
  yOffset: 5,
  minZoom: 19,
  convert: (s) => s ? s.replaceAll('-', '') : '',
  getMinZoom: (s) => s ? 18 : 0
}

filters

Replaces the built-in filter set. Keys are the onClickData fields being filtered; each value is {name, values: [...]}.

Value type Fields Matches
allnameEverything — the "Any" chip.
rangename, value1, value2value1 ≤ field < value2.
minname, value1field ≥ value1.
stringname, valueExact string match.
filters: {
  bed: {
    name: "Bedrooms",
    values: [
      {type: "all",   name: "Any"},
      {type: "range", value1: "1", value2: "2", name: "1BR"},
      {type: "min",   value1: "3", name: "3BR+"}
    ]
  },
  status: {
    name: "Status",
    values: [
      {type: "all",    name: "Any"},
      {type: "string", value: "Open for Sale", name: "Open for Sale"}
    ]
  }
}

poiOptions

The Nearby categories offered in the POI sheet. Requires displayOptions.showPOIButton.

Field Description
typeArbitrary identifier, echoed to onPOIClick.
labelText on the sliding card.
valueGoogle Places type used for the search. Must be a supported Places API type — e.g. "university", not "college".
iconIcon URL for the card. Beans-hosted icons are listed at https://api.beans.ai/enterprise/v2/search/notes/markers/info.
poiOptions: [
  { type: "FOOD",     label: "Restaurants", value: "restaurant",
    icon: "https://www.beans.ai/m/assets/food_0.png" },
  { type: "HOSPITAL", label: "Hospitals",   value: "hospital",
    icon: "https://www.beans.ai/m/assets/hospital_0.png" },
  { type: "SCHOOL",   label: "Schools",     value: "school",
    icon: "https://www.beans.ai/m/assets/school_0.png" },
  { type: "COLLEGE",  label: "Colleges",    value: "university",
    icon: "https://www.beans.ai/m/assets/school_0.png" }
]

communityAmenities

Describes the shared amenities the whole property enjoys. Setting it turns on three surfaces at once:
  1. A "Community amenities" chip row inside the unit card, plus a "See what's nearby" CTA.
  2. Amenity chips in the bottom facilities dock that pan the camera to the amenity and open its card.
  3. A rich hover card on amenity map pins, with photos and a "Click for photos & details" link.
Field Type Description
keyStringRequired. Canonical amenity identifier, e.g. "SWIMMINGPOOL".
nameStringDisplay name.
aliasesArray<String>Other identifiers this amenity answers to — both polygon descriptions and marker or POI types. Matching ignores case and punctuation. Falls back to [key].
iconUrlString (URL)Chip icon.
colorStringChip accent color.
descriptionStringCopy shown in the amenity card.
photosArray<String>Image URLs for the amenity card banner and gallery.
location{lat, lng, floor}Optional. Omit it and the camera resolves the position from the real amenity polygon on the map, which is almost always what you want.
communityAmenities: [
  {
    key: "SWIMMINGPOOL",
    name: "Swimming Pool",
    aliases: ["SWIMMINGPOOL", "POOL"],
    iconUrl: "https://www.beans.ai/m/assets/swimmingpool_0.png",
    color: "#98E3DF",
    description: "Resort-style pool with sundeck lounge seating.",
    photos: ["https://.../pool-1.jpg", "https://.../pool-2.jpg"]
  },
  {
    key: "GYM",
    name: "Fitness Center",
    aliases: ["GYM", "FITNESS"],
    iconUrl: "https://www.beans.ai/m/assets/gym_0.png",
    description: "24-hour fitness center with cardio and strength equipment.",
    photos: ["https://.../gym-1.jpg"]
  }
]

pricing

Turns on the fee calculator ("ESTIMATE YOUR COSTS") inside the unit card, below the info tiles. Requires the fees plugin:
<script src="https://www.beans.ai/mapswidget/propertymanager/plugins/fees/fees-calculator.js"></script>
<link href="https://www.beans.ai/mapswidget/propertymanager/plugins/fees/fees-calculator.css" rel="stylesheet"/>
pricing is a map of fee id to fee definition. The base rent comes from onClickData.rent, so it does not need to be repeated here.

Field Type Description
titleStringLabel shown to the renter.
categoryStringGrouping header, e.g. "Standard", "Pets", "Parking", "Amenities".
optionsArray<String>Choices the renter picks from. All the numeric arrays below are parallel to this one.
costArray<Number>Recurring monthly cost per option. null means not applicable.
annualArray<Number>Annual charge per option.
depositRefundableArray<Number>Refundable deposit per option.
applicationFeeArray<Number>One-time application fee per option.
moveInFeeArray<Number>One-time move-in fee per option.
pricing: {
  petRent: {
    title: "Pet Rent",
    category: "Pets",
    options: ["No Pet", "1 Pet", "2 Pets"],
    cost:    [0, 50, 100]
  },
  garageRental: {
    title: "Garage Rental",
    category: "Parking",
    options: ["No", "Yes"],
    cost:    [0, 200]
  }
}

callbackOptions

Event hooks back into your page. All are optional.

Callback Signature Providers Fires when
onSelect(onClickData)All A unit is selected. Receives that unit's onClickData verbatim. Only fires for units that have one.
onSelect(title, event, isOrphan)ESRI A non-unit polygon — an amenity or orphan shape — is clicked. The third argument is true in this form, so one handler can tell the two apart.
onHover(onClickData | title, event, isOrphan)ESRI The pointer enters a unit or amenity. Mirrors onSelect's two forms.
onUnitClick(ix, addressEntry, marker, event)All A unit marker is clicked, before any default behavior. Return false to suppress the default cascade (card, pan, and onSelect) and take over completely.
onPOIClick(rawStrOrName, poi, marker, event)All A POI marker or a POI row in the side panel is clicked. The first argument is the marker's full name when it contains a colon, otherwise its visible text. Return false to suppress the default note popup.
onPOINavigateClick(searchQuery)All The navigate affordance inside a POI or unit popover is pressed.
onProximityChange(newDest, prevDest, distanceM)All The user's live location comes within proximityRadiusM (default 50m) of a different marker than before. newDest is null when the user leaves every marker's radius. Requires navOptions.userLocation.
onFloorSelect(floor, floorLabel)All The selected floor changes.
onSatelliteClick(type)All The basemap toggle is used. type is "SATELLITE" or "STREET".
onMylocationClick(isFound, {lat, lng})All The my-location button resolves. On failure isFound is false and the second argument is null.
onShowOnMapClick()All The "show on map" affordance in the facilities card is pressed.
onMinimizeCard()All The Beans card is collapsed.
onMaximizeCard()All The Beans card is expanded.
onShareButtonClick()All The share button is pressed. Requires showShareButton.
onHelpButtonClick()All The help button is pressed. Requires showHelpButton.
onProximityChange destination shape
{
  type: 'unit' | 'poi',
  unitData: { ix, aug }                // when type === 'unit'
          | { rawStrOrName, poi },     // when type === 'poi'
  location: { lat, lng },
  distance: 42.7                     // metres
}
Secondary markers — entrance, parking, elevator, stair, mailroom — collapse into the 'poi' type with a synthetic poi object, so one handler covers everything.
// Callback Options
{
  onSelect: (data) => { console.log('selected', data); },
  onUnitClick: (ix, entry, marker, e) => {
    if (entry.unit === 'PENTHOUSE') {
      openMyOwnModal(entry);
      return false;   // suppress the built-in card
    }
  },
  onPOIClick: (name, poi, marker, e) => { console.log(name); },
  onFloorSelect: (floor, label) => {},
  onSatelliteClick: (type) => {},
  onMylocationClick: (isFound, pos) => {},
  onProximityChange: (dest, prev, meters) => {}
}

clientOptions — Add-Ons

The seventh argument drives ancillary-item selection: parking spaces, garages, storage units. Add-ons behave differently from unit selection — you typically highlight the tenant's unit and every available parking spot at the same time, and the tenant may be picking their first spot, changing an existing one, or adding a second.

Field Type Description
aircom.typeString"parking" (default) or "storage".
aircom.elementConfigObjectMap of Beans element id to element definition. See below.
aircom.onSelect(obj, elementConfig)Fires when the tenant confirms a selection. obj is the opaque object you attached to the element.
aircom.onUnselect(obj, elementConfig)Fires when a previously-selected element is released. Requires displayOptions.allowParkingUnselect.
aircom.onCancel()Fires when the tenant aborts the selection flow.
👉 Setting clientOptions.aircom automatically enables the floor selector, parking floor selection, all-building outlines, and bounds restriction, and switches markers to the circle shape. Override any of those explicitly in displayOptions if you need something different.

elementConfig entries
Field Type Description
idNumber / StringYour identifier for the add-on.
typeStringCategory name. Must match a key in selectableParkingShape.byNamePrefix, which supplies its color and legend text.
hoverLineArray<{key, value}>Rows shown on hover.
lineArray<{key, value}>Rows shown in the confirmation panel.
isAvailableBooleanWhether the element is colored and hoverable.
isSelectableBooleanWhether the tenant may pick it.
isEditableBooleanMarks this as the tenant's current assignment. Picking a different element releases it — the "change my parking" flow.
isDisplayableBooleanWhether the element is drawn at all.
linkedElementIdsArrayIds selected together with this one, e.g. a tandem garage pair.
restrictionString (RegExp)Only offer this element when the tenant's unit matches this pattern.
objObjectOpaque payload returned to you in onSelect and onUnselect.
👉 The Beans id for any add-on is listed at https://www.beans.ai/mapswidget/client/data/<propertyId>.json. To avoid looking them up you may namespace your own ids as 'entrata:<propertyId>:<addOnId>' and the library will resolve the Beans id for you.
// Category colors + legend, passed via displayOptions.
displayOptions.selectableParkingShape = {
  byNamePrefix: {
    "Garage Small": { text: "$155.00", fillColor: "#D08341", fillOpacity: 1 },
    "Premier":      { text: "$125.00", fillColor: "#C14634", fillOpacity: 1 },
    "Standard":     { text: "$105.00", fillColor: "#69A65B", fillOpacity: 1 }
  }
};

// One add-on, keyed by beansId (or the namespaced form described above).
elementConfig[beansId] = {
  id: 469582,
  type: "Premier",
  hoverLine: [
    { key: "Category",     value: "Premier" },
    { key: "Number",       value: "P - 65" },
    { key: "Monthly Rent", value: "$55.00" }
  ],
  line: [
    { key: "Category",     value: "Premier" },
    { key: "Number",       value: "P - 65" },
    { key: "Monthly Rent", value: "$55.00" }
  ],
  isEditable: false,
  isAvailable: true,
  isSelectable: true,
  obj: { /* returned to you in onSelect */ }
};

// Client Options — the seventh argument to render()
{
  aircom: {
    type: "parking",
    elementConfig: elementConfig,
    onSelect:   (obj, cfg) => { /* persist the assignment */ },
    onUnselect: (obj, cfg) => { /* release the old spot */ },
    onCancel:   ()         => { /* tenant backed out */ }
  }
}

Worked Example

A typical multifamily availability map: ESRI 3D, immersive layers on, unit list with filters, community amenities, and a full unit card.
<script type="text/javascript">
var be = new BeansMap();
be.render(
  "beans-maps-1",
  "...beans api key:secret...",

  // ── Addresses ─────────────────────────────────────────────────
  [
    {
      address: "1200 Dale Ave, Mountain View, CA",
      unit: "43",
      options: {
        markers: { display: false },
        onPreviewData: [
          { icon: "bed",          value: "3 Bed / 2 Bath / 1500 sq. ft." },
          { icon: "price",        value: "$3,200 / mo" },
          { icon: "availability", value: "Available Now" }
        ],
        onClickData: {
          name: "43", floorplan: "A1",
          bed: 3, bath: 2, sqft: 1500, floor: 2,
          rent: 3200, availability: "Available Now",
          floorplanImg: "https://.../plan-a1.jpg",
          images: [{url: "https://.../photo-1.jpg"}],
          tourLink: "https://.../tour",
          scheduleLink: "https://.../schedule",
          link: "https://.../apply?unit=43"
        }
      }
    }
  ],

  // ── Nav Options ───────────────────────────────────────────────
  {
    userLocation: "LIVE",
    platform: "APPLE",
    hideNavigateButton: true
  },

  // ── Display Options ───────────────────────────────────────────
  {
    initialMap: "STREET",
    camera: { tilt: 64.8, heading: 269,
              position: { x: -122.09, y: 37.40, z: 122.45 } },

    showUnitShape: true,
    showUnitList: true,
    modernBeansCard: true,
    modernButtons: true,
    outsideButtons: true,
    modernFilters: true,

    showImmersive: true,
    showImmersiveOnLoad: true,
    showCompass: true,
    showPOIButton: true,
    showSeparateFacilitiesCard: true,

    selectableUnitShape: { fillColor: '#24453E', strokeWeight: 0.5 },
    selectedUnitShape:   { fillColor: '#cc078e', strokeWeight: 0.5 },

    communityAmenities: [
      { key: "SWIMMINGPOOL", name: "Swimming Pool",
        aliases: ["SWIMMINGPOOL", "POOL"],
        iconUrl: "https://www.beans.ai/m/assets/swimmingpool_0.png",
        description: "Resort-style pool with sundeck lounge seating.",
        photos: ["https://.../pool-1.jpg"] }
    ]
  },

  // ── Callback Options ──────────────────────────────────────────
  {
    onSelect: (data) => { console.log('unit selected', data); },
    onFloorSelect: (floor, label) => {},
    onPOIClick: (name, poi, marker, e) => {}
  }
);
</script>

Support Chat Widget

The Beans.ai Web Widget comes with a support chat. It has two parts: a button that keeps a count of messages on a chat channel, and the chat interface itself, where users talk to the Beans Support team.

Button
Add a div for the button to render into. In the head of the page:
<script type="text/javascript" src="https://www.beans.ai/js/chat-widget.js"></script>
Anywhere in the body:
<div id="widget-container"></div>
Then define the button configuration in a script that runs after the DOM is ready.
<script>
  var customButtonClickHandler = () => {
    // Called when the button is clicked — trigger the display of the chat iframe here.
    alert('Please perform the necessary action');
  };

  const config = {
    // Your account id. Ask your account manager if you do not know it.
    accountBuid: '...',

    // The user talking to support. The Beans team will give you a deterministic assigneeCode format.
    assigneeCode: 'client100064237',

    // The div the button is created in.
    buttonRoot: '#widget-container',

    // Custom class name for the button.
    buttonClass: '',

    // Text written on the button.
    buttonText: '💬 Custom Chat',

    // Custom class name for the counter badge.
    badgeClass: '',

    // Custom click handler — you control when and how the iframe opens.
    onButtonClick: customButtonClickHandler,

    onInit: function(instance) {
      console.log('Widget initialized successfully');
    },

    onError: function(error) {
      console.log('Widget error: ' + error);
    }
  };

  BeansChatWidget.init(config)
</script>
Chat iframe
The Support Chat is currently integrated only as an iframe, hosted at chat.beans.ai. A sample URL:
https://chat.beans.ai/?assigneeCode=client100064237&disableLeftPanel=true#/channels/100064237
The assignee code identifies the user; the channel identifies the property the chat is about. The Beans team will give you a deterministic format for the assignee code.

Indoor Path API

The widget's wayfinding is also available as a standalone REST endpoint, for cases where you want the ordered path between indoor waypoints without rendering a map — the same engine that draws the line in displayOptions.showPath.

GET https://api.beans.ai/enterprise/v2/search/path

It is part of the address API family rather than the widget, so it is documented in full — parameters, ordering flags, and the point / leg / order response — under Enterprise API v2 → Indoor Path.