Embed API reference
Every command and event in the Icon Map embed API, generated from the SDK's TypeScript contract. Each command is a method on the handle embed() returns and resolves with the result shown, or rejects with an EmbedError whose code is one of the error codes.
A command marked read also needs the author's Read state and events switch. Types named here (EmbedCamera, EmbedScene ...) are exported by @iconmap/embed.
Commands
Session
Always available once a session is open. Not governed by the author's policy.
| Command | Arguments | Resolves with | Notes |
|---|---|---|---|
ping |
- | { protocol: number; uptimeMs: number } |
Round trip to the viewer. Useful as a liveness check, and to let an earlier asynchronous message settle. |
getCapabilities |
- | EmbedCapabilities |
The capability descriptor again (the same object ready resolved with). |
setToken |
{ token: string } |
- | Push a fresh embed token before the old one expires (see tokenExpiring). Published maps only. |
setLanguage |
{ language: string } |
- | Switch the reader language. Only a language in capabilities.map.locales; anything else rejects invalid_args, never a silent fallback. |
Camera
Move and read the view. Policy group: camera.
| Command | Arguments | Resolves with | Notes |
|---|---|---|---|
getView |
- | EmbedViewState |
read The camera and the visible bounds. |
setView |
Partial<EmbedCamera> & { animate?: boolean } |
- | Set any of center / zoom / bearing / pitch. Jumps unless animate is true. |
flyTo |
Partial<EmbedCamera> & { durationMs?: number; curve?: number } |
- | An animated flight to a camera. |
fitBounds |
{ bounds: EmbedBounds; padding?: EmbedPadding; maxZoom?: number; animate?: boolean; pitch?: number; bearing?: number } |
- | Frame a bounding box. pitch / bearing are what the camera lands on; leave them out and it keeps its current tilt (pass pitch: 0, bearing: 0 for a flat, north-up frame after a pitched flight). |
fitLayer |
{ layerId: string; padding?: EmbedPadding; maxZoom?: number; pitch?: number; bearing?: number } |
- | Frame a layer's data as currently filtered. unknown_id when the layer has no extent. pitch / bearing as for fitBounds. |
zoomBy |
{ delta: number; animate?: boolean } |
- | Zoom in or out by a delta, clamped to the map range. |
resize |
- | - | Tell the map its container changed size (after you resize the frame's parent). |
setMaxBounds |
{ bounds: EmbedBounds | null } |
- | Confine panning to a box; null removes the limit. |
Layers and visibility
Show and hide what the author published. Visibility only - never styling. Policy group: layers.
| Command | Arguments | Resolves with | Notes |
|---|---|---|---|
getLayers |
- | EmbedLayerInfo[] |
read The map's layers: id, name, kind, whether each is shown now. |
getVisibility |
- | EmbedVisibility |
read Every toggle in the scene, fully populated: layers, basemap labels and feature groups, terminator, hillshade, visuals. |
setVisibility |
EmbedVisibility |
{ skipped: string[] } | void |
Apply a partial visibility snapshot - what you leave out stays as it is. Unknown ids are skipped and reported. Hiding a slicer switches it OFF, as it does in a bookmark: its selection stops filtering until it is shown again. To filter the map without showing a card, use the filters group (setFilters). |
setLayerVisibility |
{ layerId: string; visible: boolean } |
- | Show or hide one layer. |
resetVisibility |
- | - | Return every toggle to the author's published state. |
getVisuals |
- | EmbedVisualInfo[] |
read The charts, slicers, text boxes and other visuals on the map, with their visibility. |
getLayerStats |
{ layerId: string } |
{ layerId: string; visibleFeatureCount: number } |
read How many features the layer holds right now, after filters and slicers. |
Declared filters
Values for the filters the author declared on the map. Published maps only. Policy group: filters.
| Command | Arguments | Resolves with | Notes |
|---|---|---|---|
getFilterSchema |
- | EmbedFilterSchemaEntry[] |
read The filters the author declared: name, type, operators, default. Build your own filter UI from this. |
getFilters |
- | EmbedFilterValues |
read The filter values currently applied. |
setFilters |
EmbedFilterValues |
- | Replace the filter values. A name the author did not declare rejects undeclared_filter before anything is applied. |
updateFilters |
{ operation: EmbedFilterOperation; filters?: EmbedFilterValues; display?: Record<string, EmbedFilterDisplay> } |
- | Add, replace or remove individual filters, Power BI style, with optional per-filter display settings (locked, hidden, displayName). |
clearFilters |
- | - | Remove every host filter value. |
Data
Re-run live queries. Published maps only. Policy group: data.
| Command | Arguments | Resolves with | Notes |
|---|---|---|---|
refreshData |
{ bindingIds?: string[] } | void |
{ refreshed: string[] } |
Re-run live queries past the result cache. Resolves with the binding ids refreshed (empty on a snapshot map). |
Slicers
Drive the reader's slicers. Policy group: slicers.
| Command | Arguments | Resolves with | Notes |
|---|---|---|---|
getSlicers |
- | EmbedSlicerInfo[] |
read The map's slicers and their current state. |
getSlicerValues |
{ slicerId: string; search?: string } |
{ values: unknown[]; truncated: boolean } |
read The values a list slicer offers, optionally narrowed by a search string. Works for a hidden slicer too. |
setSlicerState |
{ slicerId: string; state: EmbedSlicerState } |
- | Set one slicer's selection, exactly as if the reader had. |
clearSlicer |
{ slicerId: string } |
- | Clear one slicer. |
clearAllSlicers |
- | - | Clear every slicer. |
Selection and highlight
Select features, cross-filter charts, highlight without selecting. Policy group: selection.
| Command | Arguments | Resolves with | Notes |
|---|---|---|---|
getSelection |
- | EmbedSelection |
read The selected feature keys, by layer id. |
setSelection |
EmbedSelection |
{ skipped: string[] } | void |
Replace the selection. Unknown layer ids are skipped and reported. |
clearSelection |
- | - | Clear the selection. |
selectByKey |
{ layerId: string; keys: Array<string | number>; field?: string; zoomTo?: boolean } |
{ matched: number } |
Select features by your own keys: with field, keys are matched against that field's values ("asset 41B"); without, they are feature keys as featureClick reported them. zoomTo frames the result. At most 500 keys. field must be a column the published map carries. A published map holds only the columns it uses (tooltips, styling, labels, slicers), so a key column nothing else uses is not there and matches nothing: the author adds it to the layer's tooltip fields. |
getChartSelection |
- | Record<string, EmbedChartDatum[]> |
read The data points selected in each chart (the map's cross-filter), by chart id. |
setChartSelection |
{ chartId: string; datums: EmbedChartDatum[] } |
- | Select data points in a chart, which cross-filters the map like a click would. |
clearChartSelection |
{ chartId?: string } | void |
- | Clear one chart's selection, or all of them. |
closePopups |
- | - | Close the feature popup if one is open. |
highlight |
{ layerId: string; keys: Array<string | number>; field?: string } |
{ matched: number } |
Transient emphasis: paints keys on layerId as selected WITHOUT changing the selection - no popup, no panel scope, no selectionChanged. A reader's next click replaces it. With field, keys are resolved through that field like selectByKey. |
clearHighlight |
- | - | Remove a highlight set with highlight. |
Scenes, bookmarks and tours
Capture and restore the whole session state. Policy group: scenes.
| Command | Arguments | Resolves with | Notes |
|---|---|---|---|
captureScene |
{ include?: Array<keyof EmbedScene>; opaque?: boolean } | void |
EmbedScene | { state: string } |
read The whole session state as one serialisable object: camera, visibility, slicers, filters, selection, basemap. Store it, or turn it into a link with sceneToUrl. |
applyScene |
{ scene: EmbedScene | { state: string }; animate?: boolean } |
{ skipped: string[] } |
Restore a captured scene. Ids the map no longer has are skipped and reported, so a scene survives a republish. |
resetScene |
- | - | Return everything to the author's published state. |
getBookmarks |
- | EmbedBookmarkInfo[] |
read The author's bookmarks. Empty unless the author chose to offer bookmarks when publishing the map. |
applyBookmark |
{ bookmarkId: string; animate?: boolean } |
- | Apply a bookmark through the same path the bookmarks bar uses. |
getTours |
- | EmbedTourInfo[] |
read The author's tours. |
playTour |
{ tourId: string } |
- | Start a tour. Camera events raised while it plays carry reason: "tour". |
stopTour |
- | - | Stop the playing tour. |
Presentation
Basemap, chrome, theme, legend, image export. Policy group: presentation.
| Command | Arguments | Resolves with | Notes |
|---|---|---|---|
getBasemaps |
- | EmbedBasemapInfo[] |
read The basemaps the author published for this map, and which is active. |
setBasemap |
{ basemapId: string } |
- | Switch to one of the published basemaps. There is no way to load a style of your own. |
setChrome |
EmbedChromeSettings |
- | Hide or show the map's own controls (legend, layer control, popups, bookmarks bar, tour transport, search). A switch can hide a control the author configured; it cannot add one they did not. |
setTheme |
EmbedThemeSettings |
- | Light, dark, or follow the map. |
setBackground |
{ background: "default" | "transparent" } |
- | Make the page behind the map transparent so your own background shows through. |
getLegend |
- | EmbedLegendEntry[] |
read The legend as currently rendered, as data - build your own legend outside the frame. |
getMapInfo |
- | EmbedMapInfo |
read The map's descriptor: title, description, data mode, languages, and the attribution you must show if you hide our chrome. |
print |
- | - | Open the browser's print dialog for the map. Refused denied_capability when a sensitivity label does not allow export. |
exportImage |
EmbedExportImageArgs | void |
EmbedExportedImage |
read A PNG or JPEG of the map as the reader sees it, as a data URL. Refused denied_capability when a sensitivity label does not allow export. |
Popup menu commands
Add your own actions to the feature popup. Policy group: commands.
| Command | Arguments | Resolves with | Notes |
|---|---|---|---|
addMenuCommand |
EmbedMenuCommand |
- | Add your own action to the feature popup. Only a plain-text title and an id cross into the frame - never HTML or script. Clicking it raises menuCommandTriggered. |
removeMenuCommand |
{ id: string } |
- | Remove a popup action you added. |
getMenuCommands |
- | Array<{ id: string; title: string }> |
read The popup actions you have added. |
Analysis
Run a layer's analysis engine, where a map has one. Policy group: analysis.
| Command | Arguments | Resolves with | Notes |
|---|---|---|---|
getAnalysisOps |
- | EmbedAnalysisOp[] |
read The analysis operations this map answers, each with its layer and argument hints. Empty when the map has no analysis engine. |
runAnalysis |
{ op: string; layerId?: string; args?: Record<string, unknown> } |
EmbedAnalysisResult |
Run one analysis operation. One runs per layer at a time; up to 4 wait (busy beyond that); 60 a minute per session (budget_exceeded). Large results are capped and marked truncated. |
getClock |
{ layerId?: string } | void |
EmbedClockState | null |
read An analysis layer's simulation clock, or null when it has none. |
setClock |
{ simSeconds: number; layerId?: string } |
EmbedClockState |
Move an analysis layer's simulation clock. |
On the handle only
These run in your page, not in the map, so they never appear in capabilities.commands.
| Member | What it does |
|---|---|
ready |
A promise for the capability descriptor. Rejects with denied_origin when your origin is not allowed. |
capabilities, protocol |
What this viewer answers, once known. |
on(name, handler) / off(name) |
Subscribe to an event; on returns an unsubscribe function. |
render(options) |
Complete a deferred embed (deferRender: true). |
reload() |
Reload the frame. Subscriptions are restored when the new session opens. |
fullscreen() / exitFullscreen() |
Full screen the frame. Call from a click handler - browsers require a user gesture on your page. |
destroy() |
Remove the frame and reject anything in flight with destroyed. |
iframe |
The mounted <iframe> element. |
Events
Nothing is sent until you subscribe (handle.on(name, handler) or the events option). Every event carries a session-wide seq; a gap means one was dropped. State events carry a reason - "user", "command", "bookmark", "tour", "scene" or "load" - so a two-way sync can ignore its own echo.
| Event | Payload | Notes |
|---|---|---|
loaded |
- | The map rendered (the v1 onLoad). |
rendered |
{ durationMs: number } |
First idle frame: the map's own data is on screen. durationMs is from frame start. |
viewChanged |
EmbedViewState & { reason: EmbedChangeReason } |
The camera settled (or, with continuousView, moved). Throttled; the last value always arrives. |
visibilityChanged |
{ visibility: EmbedVisibility; reason: EmbedChangeReason } |
A layer, visual or basemap toggle changed. |
filtersChanged |
{ filters: EmbedFilterValues; reason: EmbedChangeReason } |
The host filter values changed. |
slicerChanged |
{ slicerId: string; state: EmbedSlicerState; reason: EmbedChangeReason } |
A slicer selection changed. |
selectionChanged |
{ selection: EmbedSelection; reason: EmbedChangeReason } |
The selection changed. |
featureClick |
EmbedFeatureClick | null |
The reader clicked a feature (null = clicked empty map). fields holds the layer's tooltip fields only - what the reader can already see. |
featureHover |
EmbedFeatureClick | null |
The pointer entered a feature (null = left). Off unless you subscribe; spaced at least 100 ms apart, and a leave is never delayed. |
linkClicked |
{ url: string; layerId?: string; featureKey?: string | number; buttonId?: string } |
A hyperlink or link button was clicked, when hyperlinkBehavior is raiseEvent or navigateAndRaiseEvent. Route it inside your own app. |
menuCommandTriggered |
{ commandId: string; layerId: string; featureKey: string | number; fields: Record<string, unknown> } |
The reader chose a popup action you added with addMenuCommand. |
chartSelectionChanged |
{ chartId: string; datums: EmbedChartDatum[]; reason: EmbedChangeReason } |
A chart's selected data points changed. |
bookmarkApplied |
{ bookmarkId: string } |
A bookmark was applied - by the reader, a tour, or you. |
tourStateChanged |
{ tourId: string | null; state: "started" | "keyframe" | "ended" } |
A tour started, reached a keyframe, or ended. |
basemapChanged |
{ basemapId: string } |
The active basemap changed. |
themeChanged |
{ mode: string } |
The theme changed. |
dataStateChanged |
{ state: "loading" | "ready" | "stale" | "error"; bindingIds?: string[]; reason?: string } |
Live data started loading, became ready, went stale, or failed. |
tokenExpiring |
{ expiresInMs: number } |
The embed token expires in expiresInMs (raised 60 s ahead). Answer with setToken. |
error |
EmbedErrorInfo |
A viewer error after the session opened. |
viewerResized |
{ width: number; height: number } |
The map container changed size. |
analysisResult |
EmbedAnalysisResult & { reason: EmbedChangeReason } |
An analysis op completed - whether the reader clicked or the host commanded. |
clockChanged |
EmbedClockState & { reason: EmbedChangeReason } |
An analysis layer's engine clock moved (throttled, EMBED_LIMITS.clockIntervalMs). |
Error codes
| Code | Meaning |
|---|---|
unsupported_protocol |
The viewer and the SDK share no protocol version. |
unsupported_command |
This viewer build, this embed surface, or this map does not answer the command. Check capabilities.commands first. |
denied_capability |
The map's author has not enabled the command's group (or read access), or a sensitivity label refuses an export. |
denied_origin |
Your page's origin is not on the map's allowed origins, so no control session opened. |
invalid_args |
The arguments failed validation. message says which one. |
not_ready |
The part of the map the command needs did not become available within 10 seconds. Commands sent early are held, not refused, so this means the map failed to start - check onError. |
unknown_id |
A layer, bookmark, tour, slicer, chart, basemap or analysis op id that this map does not have. |
undeclared_filter |
setFilters named a filter the author did not declare. detail.undeclared lists them. |
rate_limited |
More than 60 commands in one second, or the backend's rate limit on a data refresh. |
budget_exceeded |
The per-session analysis budget, or the publish's query budget, is spent. |
too_large |
The command message exceeded EMBED_LIMITS.maxCommandBytes. |
busy |
Too many analysis commands are already waiting on that layer. |
data_error |
The backend failed a data request. Quote requestId in a support report. |
auth_required |
The embed token is missing, expired or refused. Supply getToken or call setToken. |
timeout |
The viewer did not answer within the command timeout (SDK-side). |
destroyed |
The handle was destroyed, or the frame reloaded, while the command was in flight (SDK-side). |
internal |
The command threw unexpectedly. detailedMessage has the cause. |
Limits
Fixed by the viewer (EMBED_LIMITS in the SDK). A host cannot raise them and an author cannot lower them.
| Limit | Value |
|---|---|
| Largest command message | 64 KB - larger is refused too_large |
| Largest event payload | 32 KB - larger is dropped (you see a seq gap) |
Keys in one highlight / selectByKey |
500 |
| Ids in an analysis result | 1000 - then truncated: true |
| Rows in an analysis result | 200 - then truncated: true |
| Analysis commands per session | 60 a minute - then budget_exceeded |
| Analysis commands waiting on one layer | 4 - then busy |
featureHover spacing |
100 ms (the last value always arrives) |
clockChanged spacing |
250 ms (the last value always arrives) |
| Commands per second | 60 - then rate_limited |