For the complete documentation index, see llms.txt. This page is also available as Markdown.

Analytics

Read localization query logs and spatial heatmaps over the REST API.

These endpoints expose the data behind the Analytics section of the Developer Portal, so you can pull the same numbers into your own dashboards, reports, or scheduled jobs. Two endpoints are available:

  • Query logs — every localization request recorded for your account, newest first, with an aggregate recall summary.

  • Heatmap — where inside a map or map set those requests came from, pre-binned and ready to render.

For the portal UI built on top of these, see Analytics and Usage.

Both endpoints accept the codes you already use elsewhere in the API — mapCode, mapSetCode, and objectCode.

Access

Both endpoints need a Bearer token, and are available to:

  • User tokens with any role that carries read permission.

  • M2M clients holding the query scope. See Authentication for issuing an M2M token.

If you are calling from a browser, your site's domain must be registered against the account first, otherwise the request is rejected before it reaches the endpoint. See Configuring Allowed Domains (CORS).

A code that does not belong to your account returns 404, the same as one that does not exist.

Query Logs

Returns individual localization requests with their timestamp, whether a pose was found, and — on successful requests — the resolved position, rotation, and confidence. Results are paginated, newest first.

Scope the log to a map, a map set, or an object:

Target
Parameter
Example

Map

mapCode

MAP_XZPGP5EPHGBX

Map set

mapSetCode

MSET_7QJW2XKD8PLM

Object

objectCode

OBJ_4KDMQ2WRTB91

If you scope to more than one target, they are applied in the order map → map set → object and only the first takes effect. Supplying none returns every request made against a map. When neither date is given, the range defaults to the last 30 days.

Each returned record carries the code of whatever it was queried against — mapCode, mapSetCode, or objectCode — alongside its name, so you can group and label results without a second lookup.

A record that resolved a pose carries position, rotation, and confidence; one that did not omits those three fields entirely:

Query logs and recall summary

get

Returns the individual localization requests recorded for your account, newest first, together with an account-wide recall summary for the same period.

Scope the log to a map, a map set, or an object with mapCode, mapSetCode, or objectCode. Scoping to more than one target applies them in the order map → map set → object, and only the first takes effect. With none supplied, the log falls back to every request made against a map.

Note that summary is deliberately not scoped by the filter — it always covers the whole account for the selected date range, so summary.total and totalCount will differ whenever a filter is applied.

Authorizations
AuthorizationstringRequired
Bearer authentication header of the form Bearer <token>.
Query parameters
mapCodestringOptional

Restrict the log to a single map, by its mapCode.

Example: MAP_XZPGP5EPHGBX
mapSetCodestringOptional

Restrict the log to a single map set. Ignored if a map is also supplied.

Example: MSET_7QJW2XKD8PLM
objectCodestringOptional

Restrict the log to a single tracked object. Ignored if a map or map set is also supplied.

Example: OBJ_4KDMQ2WRTB91
startDatestring · date-timeOptional

ISO 8601 start of the range. Defaults to 30 days ago when neither date is given.

Example: 2026-08-01T00:00:00.000Z
endDatestring · date-timeOptional

ISO 8601 end of the range. Must be greater than or equal to startDate.

Example: 2026-09-01T00:00:00.000Z
pageinteger · min: 1Optional

1-based page number.

Default: 1
limitinteger · min: 1 · max: 100Optional

Records per page. Capped at 100.

Default: 50
Responses
200

Query logs retrieved successfully

application/json
totalCountintegerOptional

Total records matching the filter.

Example: 1342
currentPageintegerOptionalExample: 1
totalPagesintegerOptionalExample: 27
limitintegerOptionalExample: 50
get/account/analytics/query-api
GET /v1/account/analytics/query-api HTTP/1.1
Host: api.multiset.ai
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
  "logs": [
    {
      "timestamp": "2026-09-01T10:15:30.000Z",
      "poseFound": true,
      "mapId": "68f0a1b2c3d4e5f60718293a",
      "mapName": "Office Floor 3",
      "mapCode": "MAP_XZPGP5EPHGBX",
      "mapSetId": "68f0a1b2c3d4e5f60718293b",
      "mapSetName": "HQ Campus",
      "mapSetCode": "MSET_7QJW2XKD8PLM",
      "objectId": "68f0a1b2c3d4e5f60718293c",
      "objectName": "Control Panel",
      "objectCode": "OBJ_4KDMQ2WRTB91",
      "position": {
        "x": 2.482360321597187,
        "y": 0.11936171927197065,
        "z": 8.06609995252609
      },
      "rotation": {
        "x": 0.02949315565629783,
        "y": 0.7673793569590026,
        "z": -0.01740867960782986,
        "w": 0.6402780756491143
      },
      "confidence": 0.459232334365416,
      "isRightHanded": false
    }
  ],
  "totalCount": 1342,
  "currentPage": 1,
  "totalPages": 27,
  "limit": 50,
  "summary": {
    "total": 4820,
    "poseFoundTrue": 3947,
    "poseFoundFalse": 873,
    "maps": {
      "total": 4102,
      "poseFoundTrue": 3390,
      "poseFoundFalse": 712
    },
    "objects": {
      "total": 718,
      "poseFoundTrue": 557,
      "poseFoundFalse": 161
    }
  }
}

Localization Heatmap

Returns the spatial density of successful localizations. Only requests that resolved a pose contribute a position.

The single path segment takes either a mapCode or a mapSetCode, and the prefix decides which:

You pass
You get

MAP_…

The heatmap for that one map.

MSET_…

The combined heatmap for every query made against that map set.

The response identifies its subject accordingly — mapId, mapCode, and mapName for a map; mapSetId, mapSetCode, and mapSetName for a map set.

Rather than shipping raw points, the API bins them into a uniform voxel grid and collapses each occupied cell to its centroid, so a few thousand requests arrive as a few hundred weighted points. Each point carries:

Field
Meaning

x, y, z

Centroid of the voxel, in render space.

weight

Raw number of requests that fell in that voxel.

normalizedWeight

Log-scaled density from 0 to 1, where the busiest voxel in the response is 1.0. Feed this straight into a color ramp.

normalizedWeight is log-scaled rather than linear so that low-traffic areas stay visible next to a dominant hotspot. A few entries from positions show the effect — a 522-to-1 spread in raw weight lands at 1.0 against 0.11, instead of collapsing to near zero:

It is scoped to a single response — the busiest voxel is always 1.0 — so values are not comparable between two calls. To compare periods, use the raw weight.

Note also that summary.total counts every request, while only the poseFoundTrue ones contribute a position, so the weights sum to less than the total.

Control the resolution with binSize (metres, 0.05–10, default 0.25). Smaller bins give finer detail and more points; larger bins give coarser, cheaper output. When neither date is given, the range defaults to the last 7 days.

Coordinate space. Unlike the query logs, this endpoint returns a single frame: every position is right-handed (Three.js) render space. Records captured left-handed — Unity, and anything that queried without isRightHanded — are converted server-side by negating x before binning, so both sources merge into one consistent set and no conversion is needed client-side. Binning them un-normalised would place one physical spot in two mirrored cells. See Coordinate Systems for the wider convention.

Localization heatmap for a map or map set

get

Returns the spatial density of successful localizations, ready to render. Raw positions are binned into a uniform voxel grid and each occupied cell is collapsed to its centroid, so a few thousand requests come back as a few hundred weighted points.

Every position is normalised into a single right-handed (Three.js) render space before clustering. Left-handed (Unity) records are converted by negating x, so both sources merge into one consistent set and the client only has to render.

Only requests where a pose was found contribute positions. The summary counts, unlike those on the query-api endpoint, are scoped to the map or map set requested.

Authorizations
AuthorizationstringRequired
Bearer authentication header of the form Bearer <token>.
Path parameters
codestringRequired

The subject of the heatmap: either a map's mapCode or a map set's mapSetCode. The prefix selects which, so MAP_… returns one map's heatmap and MSET_… returns the combined heatmap for every query made against that map set.

Example: MAP_XZPGP5EPHGBX
Query parameters
startDatestring · date-timeOptional

ISO 8601 start of the range. Defaults to 7 days ago when neither date is given.

Example: 2026-09-01T00:00:00.000Z
endDatestring · date-timeOptional

ISO 8601 end of the range. Must be greater than or equal to startDate.

Example: 2026-09-08T00:00:00.000Z
binSizenumber · min: 0.05 · max: 10Optional

Voxel edge length in metres. Smaller values give finer detail and more points, larger values give coarser, cheaper output.

Default: 0.25Example: 0.25
Responses
200

Heatmap retrieved successfully

application/json
mapIdstringOptional

Returned when the heatmap is for a map.

Example: 68f0a1b2c3d4e5f60718293a
mapCodestringOptional

Returned when the heatmap is for a map.

Example: MAP_XZPGP5EPHGBX
mapNamestringOptional

Returned when the heatmap is for a map.

Example: Office Floor 3
mapSetIdstringOptional

Returned instead of the map fields when the heatmap is for a map set.

Example: 68f0a1b2c3d4e5f60718293b
mapSetCodestringOptional

Returned instead of the map fields when the heatmap is for a map set.

Example: MSET_7QJW2XKD8PLM
mapSetNamestringOptional

Returned instead of the map fields when the heatmap is for a map set.

Example: HQ Campus
accountIdstringOptionalExample: 68f0a1b2c3d4e5f607182939
binSizenumberOptional

The bin size actually applied.

Example: 0.25
get/account/analytics/heatmap/{code}
GET /v1/account/analytics/heatmap/{code} HTTP/1.1
Host: api.multiset.ai
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
  "mapId": "68f0a1b2c3d4e5f60718293a",
  "mapCode": "MAP_XZPGP5EPHGBX",
  "mapName": "Office Floor 3",
  "mapSetId": "68f0a1b2c3d4e5f60718293b",
  "mapSetCode": "MSET_7QJW2XKD8PLM",
  "mapSetName": "HQ Campus",
  "accountId": "68f0a1b2c3d4e5f607182939",
  "binSize": 0.25,
  "positions": [
    {
      "x": 2.4901,
      "y": 0.1204,
      "z": 8.0617,
      "weight": 522,
      "normalizedWeight": 1
    }
  ],
  "summary": {
    "total": 1342,
    "poseFoundTrue": 1105,
    "poseFoundFalse": 237
  }
}

Last updated

Was this helpful?