Platform Methods
Access TelemetryOS platform features including accounts, users, devices, applications, and proxy services for external content fetching.
Platform Methods
Access to accounts, users, devices, applications, and proxy services.
Overview
These methods provide access to TelemetryOS platform features and information:
- Accounts - Current account information
- Users - Current user information
- Devices - Device hardware information
- Applications - Application discovery and embedding
- Environment - Color scheme detection and subscription
Accounts API
Access information about the current TelemetryOS account.
Import
import { accounts } from '@telemetryos/sdk';getCurrent()
Retrieve current account information.
Signature:
async getCurrent(): Promise<CurrentAccount>CurrentAccount Type:
type CurrentAccount = {
id: string;
name: string;
industry?: string;
country?: string;
region?: string;
timezone?: string;
language?: string;
timeFormat?: string;
currencySymbol?: string;
}Returns: Promise resolving to the current account
Example:
const account = await accounts().getCurrent();Users API
Access information about the current user.
Import
import { users } from '@telemetryos/sdk';getCurrent()
Retrieve current user information.
Signature:
async getCurrent(): Promise<CurrentUser>CurrentUser Type:
type CurrentUser = {
id: string;
email: string;
firstName: string;
lastName: string;
companyName: string;
avatarUrl: string;
}Returns: Promise resolving to the current user
Note: Only Studio has a user context — a player authenticates as a device, not
a person — so this rejects when running on a player.
Example:
const user = await users().getCurrent();Devices API
Access device hardware information.
Import
import { devices } from '@telemetryos/sdk';getCurrent()
Retrieve the logical device record — the admin-configured identity and context the
application is running on. This is distinct from getInformation() (the static
hardware fingerprint) and getMetrics() (live runtime telemetry); it changes when an
admin renames, moves, or retags the device.
Signature:
async getCurrent(): Promise<Device | null>Device Type:
type Device = {
id: string;
name: string;
description: string;
assetId: string;
location: string;
geo: DeviceGeo | null;
tags: string[];
language: string;
}
type DeviceGeo = {
latitude: number;
longitude: number;
timezone: string;
}geo is null when the admin has not configured a location, rather than defaulting
to (0, 0) — which would be indistinguishable from a real location in the Gulf of
Guinea.
Returns: Promise resolving to the device, or null when there is no device context
Example:
const device = await devices().getCurrent();subscribeCurrent()
Subscribe to changes to the device record. The handler is invoked immediately with the
current value, then again whenever it changes.
Signature:
async subscribeCurrent(handler: (device: Device | null) => void): Promise<boolean>Example:
await devices().subscribeCurrent((device) => {
console.log('Device is now', device?.name);
});unsubscribeCurrent()
Signature:
async unsubscribeCurrent(handler?: (device: Device | null) => void): Promise<boolean>Omit the handler to remove all of them.
getInformation()
Retrieve hardware information about the current device.
Signature:
async getInformation(): Promise<DeviceInformation>DeviceInformation Type:
type DeviceInformation = {
serialNumber: string;
model: string;
manufacturer: string;
platform: string;
}Returns: Promise resolving to device information
Example:
const info = await devices().getInformation();Note: Only available on physical devices (not in admin portal)
getMetrics()
Retrieve live runtime telemetry for the device. These values change continuously —
prefer subscribeMetrics() over polling this in a loop.
Signature:
async getMetrics(): Promise<DeviceMetrics | null>DeviceMetrics Type:
type DeviceMetrics = {
cpuLoadPercent: number;
memoryUsedPercent: number;
cacheUsagePercent: number;
uptimePercent: number;
}Example:
const metrics = await devices().getMetrics();subscribeMetrics()
Signature:
async subscribeMetrics(handler: (metrics: DeviceMetrics | null) => void): Promise<boolean>unsubscribeMetrics()
Signature:
async unsubscribeMetrics(handler?: (metrics: DeviceMetrics | null) => void): Promise<boolean>getCapabilities()
Retrieve what hardware and software features the device supports, so an application can
enable features conditionally.
Signature:
async getCapabilities(): Promise<DeviceCapability[] | null>DeviceCapability Type:
type DeviceCapability =
| 'configurableDisplays'
| 'configurableAudio'
| 'applicationContainers'
| 'applicationManagement'
| 'resourceCaching'
| 'bluetooth'
| 'wiFi'
| 'ethernet'
| 'usbProvisioning'
| 'videoStreaming'
| 'screenCaptureStreaming'
| 'mqtt'
| 'onScreenKeyboard'The same list is exported as a runtime array, deviceCapabilities, for validation.
Returns: Promise resolving to the capability list, null when there is no device
context, or an empty array when the device is known but exposes none
Example:
const capabilities = await devices().getCapabilities();
if (capabilities?.includes('mqtt')) {
// Safe to use the MQTT API
}getRootApplicationSpecifier()
Retrieve the application specifier of the root application hosting this one — for
example the layout or playlist renderer it is embedded under.
Signature:
async getRootApplicationSpecifier(): Promise<string | null>Returns: Promise resolving to the specifier, or null when there is no root
application context
Example:
const root = await devices().getRootApplicationSpecifier();Applications API
Discover and embed other TelemetryOS applications.
Import
import { applications } from '@telemetryos/sdk';getAllByMountPoint()
Find all applications with a specific mount point.
Signature:
async getAllByMountPoint(mountPoint: string): Promise<Application[]>Application Type:
type Application = {
name: string;
mountPoints: Record<string, MountPoint>;
}
type MountPoint = {
path: string;
[key: string]: any;
}Parameters:
mountPoint- Mount point identifier to search for
Returns: Array of applications with that mount point
Example:
const widgets = await applications().getAllByMountPoint('dashboard-widget');getByName()
Find a specific application by name.
Signature:
async getByName(name: string): Promise<Application | null>Parameters:
name- Application name
Returns: Application object or null if not found
Example:
const weatherApp = await applications().getByName('weather-widget');setDependencies()
Declare application dependencies for preloading.
Signature:
async setDependencies(applicationSpecifiers: string[]): Promise<{
ready: string[];
unavailable: string[];
}>Parameters:
applicationSpecifiers- Array of application specifier strings
Returns: Object with ready and unavailable arrays
Example:
const result = await applications().setDependencies([
'weather-widget-hash123',
'news-ticker-hash456'
]);Important: Call and await setDependencies() before loading sub-applications in iframes.
Environment API
Access environment settings including color scheme preferences, online status, and the runtime host the application is running in.
Import
import { environment } from '@telemetryos/sdk';ColorScheme Type
type ColorScheme = 'light' | 'dark' | 'system'EnvironmentType Type
The runtime host an application is running in.
type EnvironmentType = 'studio' | 'player' | 'web' | 'companion' | 'development'getColorScheme()
Retrieve the current color scheme setting.
Signature:
async getColorScheme(): Promise<ColorScheme>Returns: Promise resolving to the current color scheme
Example:
const colorScheme = await environment().getColorScheme();subscribeColorScheme()
Subscribe to color scheme changes.
Signature:
async subscribeColorScheme(handler: (colorScheme: ColorScheme) => void): Promise<boolean>Parameters:
handler- Callback function invoked when the color scheme changes
Returns: Promise resolving to true if subscription was successful
Example:
await environment().subscribeColorScheme((colorScheme) => {
console.log('Color scheme changed:', colorScheme);
});unsubscribeColorScheme()
Unsubscribe from color scheme changes.
Signature:
async unsubscribeColorScheme(handler?: (colorScheme: ColorScheme) => void): Promise<boolean>Parameters:
handler- Optional. The specific handler to remove. If omitted, all handlers are removed.
Returns: Promise resolving to true if unsubscription was successful
Example:
await environment().unsubscribeColorScheme();getCurrent()
Retrieve the runtime host the application is running in. Useful for adapting behavior per host — for example, showing different UI in Studio versus on a Player, or enabling dev-only tooling.
Signature:
async getCurrent(): Promise<EnvironmentType>Returns: Promise resolving to the current EnvironmentType
Example:
const env = await environment().getCurrent();
if (env === 'player') {
// Running on a digital signage player
}getIsOnline()
Retrieve whether the application currently has network connectivity.
Signature:
async getIsOnline(): Promise<boolean>Returns: Promise resolving to true when online, false when offline
Example:
const isOnline = await environment().getIsOnline();subscribeIsOnline()
Subscribe to online/offline status changes. The handler is invoked immediately with the current value, then again whenever connectivity changes — letting an app react when it comes back online (for example, reloading APIs or media).
Signature:
async subscribeIsOnline(handler: (isOnline: boolean) => void): Promise<boolean>Parameters:
handler- Callback function invoked with the online status, and again on every change
Returns: Promise resolving to true if subscription was successful
Example:
await environment().subscribeIsOnline((isOnline) => {
if (isOnline) {
// Back online — refresh data
}
});unsubscribeIsOnline()
Unsubscribe from online/offline status changes.
Signature:
async unsubscribeIsOnline(handler?: (isOnline: boolean) => void): Promise<boolean>Parameters:
handler- Optional. The specific handler to remove. If omitted, all handlers are removed.
Returns: Promise resolving to true if unsubscription was successful
Example:
await environment().unsubscribeIsOnline();getDisplayProperties()
Retrieve the properties of the display the application is rendered on, including its
overall size in pixels across every screen.
Signature:
async getDisplayProperties(): Promise<DisplayProperties>DisplayProperties Type:
type DisplayProperties = {
/** Overall display width in pixels, spanning all screens. */
width: number
/** Overall display height in pixels, spanning all screens. */
height: number
}The type is intentionally extensible — future fields such as per-screen geometry,
orientation, or device pixel ratio may be added without a breaking change, so treat
unknown fields as optional.
Example:
const { width, height } = await environment().getDisplayProperties();Availability: currently served only when your application runs inside a root
application that provides it (the layout renderer). Elsewhere nothing answers the
request, so it rejects after the SDK's 30-second timeout — catch it and fall back
rather than blocking your render path on the result.
subscribeDisplayProperties()
Subscribe to display-property changes. The handler is invoked immediately with the
current value, then again whenever it changes.
Signature:
async subscribeDisplayProperties(handler: (properties: DisplayProperties) => void): Promise<boolean>Example:
await environment().subscribeDisplayProperties(({ width, height }) => {
console.log(`Display is now ${width}x${height}`);
});unsubscribeDisplayProperties()
Signature:
async unsubscribeDisplayProperties(handler?: (properties: DisplayProperties) => void): Promise<boolean>Omit the handler to remove all of them.
setRootSettingsNavigation()
Register navigation entries for a root application in the TelemetryOS Studio UI sidebar. Your entries are merged into Studio's built-in navigation, letting you surface your own management screens (for example "Canvases" or "Channels") alongside the built-in ones.
This is a root-application, worker-only API. Call it from a background worker — mount-point contexts (
render/settings) are transient iframes, so the worker is the single stable place to own the nav definition. Calling it from a mount point throws. It is fire-and-forget (returnsvoid), so do notawaitit. Root applications importenvironmentfrom@telemetryos/root-sdk(also re-exported from@telemetryos/sdk).
Signature:
setRootSettingsNavigation(navigation: RootSettingsNavigationOpts): voidPayload types:
type RootSettingsNavigationOpts = {
sections: NavEntry[]
}
type NavEntry = {
key: string // camelCase id, unique among its siblings
title?: string // display label (omit on reference-only entries)
icon?: NavEntryIcon
path?: string // sub-path within your rootSettings mount point
url?: string // absolute external link (opens in a new tab); path wins if both set
permissions?: string[] // user needs at least one; empty/undefined = no gate
before?: string | string[] // position before a sibling key (first match wins)
after?: string | string[] // position after a sibling key (wins over `before`)
items?: NavEntry[] // children (recursive)
}
type NavEntryIcon = {
name?: string // one of Studio's curated icon keys (see below)
svg?: string // raw SVG (DOMPurify-sanitized); use currentColor
}Parameters:
navigation- The sidebar sections to contribute.sectionsmay reference built-in sections bykey(to nest items into them) and/or declare new top-level sections.
Returns: void (fire-and-forget; do not await)
Example — nest an item under a built-in section:
import { environment } from '@telemetryos/root-sdk';
// Runs in a background worker (e.g. src/background-worker.ts)
environment().setRootSettingsNavigation({
sections: [
{
key: 'content', // built-in Studio section
items: [
{ key: 'canvases', title: 'Canvases', icon: { name: 'image' }, path: '/', after: 'media' },
],
},
],
});Example — a full navigation tree (multiple sections):
Imagine a root application that manages self-service ordering across a restaurant chain — menus, restaurants and their kiosks, and orders. It contributes three top-level sections (each anchored after the relevant built-in one) with eight screens between them:
environment().setRootSettingsNavigation({
sections: [
{
key: 'menu',
title: 'Menu',
after: 'content', // place this section after the built-in Content section
items: [
{ key: 'menuBoards', title: 'Menu Boards', icon: { name: 'grid' }, path: '/menu/boards' },
{ key: 'menuItems', title: 'Items & Pricing', icon: { name: 'book' }, path: '/menu/items' },
{
key: 'dayparts',
title: 'Dayparts',
// No clock in the curated icon set — use a custom SVG (currentColor so it themes)
icon: {
svg: '<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="9" fill="none" stroke="currentColor" stroke-width="2"/><path d="M12 7v5l3 2" fill="none" stroke="currentColor" stroke-width="2"/></svg>',
},
path: '/menu/dayparts',
},
],
},
{
key: 'restaurants',
title: 'Restaurants',
after: 'devices',
items: [
{ key: 'locations', title: 'Locations', icon: { name: 'map' }, path: '/restaurants/locations' },
{ key: 'kiosks', title: 'Kiosks', icon: { name: 'devices' }, path: '/restaurants/kiosks' },
],
},
{
key: 'orders',
title: 'Orders',
after: 'data',
items: [
{ key: 'liveOrders', title: 'Live Orders', icon: { name: 'dashboard' }, path: '/orders/live' },
{
key: 'orderHistory',
title: 'Order History',
icon: { name: 'database' },
path: '/orders/history',
after: 'liveOrders', // sibling anchor within the Orders section
},
{
key: 'orderReports',
title: 'Reports',
icon: { name: 'analytics' },
path: '/orders/reports',
permissions: ['orders.reports'], // hidden unless the user holds this permission
},
],
},
],
});Contribution shapes:
- Nest under a built-in section — reference the section by
keyand put your items initems. On a reference entry Studio keeps the section's own title/icon ("first contributor wins"), so put display fields on the child. - New top-level section — a top-level entry with
itemsrenders as an uppercase header plus clickable children. - Do not contribute a bare top-level leaf (a top-level entry with
path/titlebut noitems) — Studio renders the top level as non-clickable headers and drops childless top-level nodes, so it renders nothing.
Built-in anchor keys — before/after (and reference entries) resolve against these current built-in keys. Anchors are sibling-scoped (a key only resolves at its own level), and these keys may change over time:
| Level | Keys |
|---|---|
| Top-level sections | home, devices, content, data, settings |
Under content | playlists, media, applications, campaigns, overrides |
Under devices | devicesIndex, devicesGrid, devicesMap, reports |
Under data | campaignLogs, accountLogs, deviceLogs, playbacks |
Under home | dashboard |
Icons — icon.name must be one of Studio's curated keys: alert, analytics, apps, book, campaign, chart, content, dashboard, database, device, devices, grid, home, image, map, media, package, playlist, playlists, settings, user, users. Unknown names render no icon. For anything else supply icon.svg with a raw SVG string (DOMPurify-sanitized; use currentColor so it follows Studio's theme).
See Background Workers for how to declare and build a worker, and the Settings mount point for related per-instance configuration.
Next Steps
- Storage API - Store application data
- Code Examples - Complete integration examples
- Client API - Low-level messaging API
Updated 23 days ago