Developer
API
Websockets
API Commands

API Commands

Interacting with the API is split into two groups of commands, one way commands and two way commands.

One way commands are simple, and are just a command that you send to tell the overlay to do something.

Two way commands are commands that, after completing the requested task, the overlay will send you back a response. These commands should be handled in your websocket's OnMessage event.

One Way Commands

ToggleLayoutMode

Toggles layout mode on or off.


TogglePerformanceStats

Toggles performance overlay on or off.


Create

Layout mode toolbar create button, creates an overlay.


Recenter

Layout mode toolbar recenter button, Re-centers the overlay space.


Keyboard

Layout mode toolbar keyboard button. Summons / dismisses the keyboard.


Layouts

Layout mode toolbar layouts folder button. Summons / dismisses the layout folder.


Settings

Layout mode toolbar settings button. Summons / dismisses settings panel.


DeleteAll

Layout mode toolbar delete button. Deletes all active overlays.


WindowSwitcher

Layout mode toolbar grid view button.


MediaPlayPause

Plays/Pauses the media player.


MediaPrevious

Goes back to previous media.


MediaNext

Skips to next media.


WindowSettings

Toggles if the window settings panel is visible.


WindowSelect

Toggles if the window select panel is visible.


WindowDelete

Deletes the overlay that has ownership of the window toolbar.


UpdateMediaPlayerInformation

Updates the media player information with an XSOMediaObject.

XSOMediaObject Object
{
    "title": string, 
    "album": string, 
    "artist": string, 
    "albumArt": string, // base64 encoded image
    "applicationName": string, // spotify, youtube, etc
    "playbackStatus": string // "playing" or "paused" 
}

SetXSOverlaySystemSetting

Sets a user settings. You can find the names in the settings and what they do with the GetSettings return object.

Setting Object
{
    "internalName": string,
    "value": object // type depends on setting
}

SetActiveOverlaySetting

Sets a setting on the currently active overlay. Utilizes the setting object. Each overlay has these options.

PropertyTypeDescription
pinboolWhen enabled, the overlay is pinned.
autoHideboolWhen enabled, the overlay will auto hide when not within the clipping angle
lockboolWhen enabled, the overlay lock and will not be able to be moved or adjusted
opacityfloatOpacity of the overlay, between 0 and 1
blockInputboolWhen enabled, the overlay will not accept inputs.
brightnessfloatBrightness of the overlay, between 0 and 1
maxFPSintMaximum FPS of the overlay
minFPSintMinimum FPS of the overlay
trackingSpaceintThis could be mixed (0), head (1), or hand (2)
captureSelectintThis is either Windows Game Capture (0) or BitBlt (1)

RequestShowTooltip

Requests to show a tooltip.


PlayDeviceHaptics

Allows you to play haptic feedback on a device.

Haptics Object
{
    "deviceId": string, // Accepts int or "leftcontroller" / "rightcontroller"
    "duration": int // in milliseconds
}
Example.js
    Api.Send(Api.Commands.PlayDeviceHaptics, JSON.stringify(new Api.HapticsObject('deviceId', 500)));

OpenSteamVRBindings

Opens the SteamVR Binding Dashboard Page for XSO


SendNotification

Sends a notification.

💡

Websocket notification format is slightly different from UDP notification format. Please make sure your notification object is up to date.

Notification Markup

Websocket Notification Object

PropertyTypeDescriptionDefault Value
typeintThe type of message to send. 1 defines a normal notification.1
indexintUsed for Media Player, changes the icon on the wrist. (depricated, see note below)0
timeoutfloatHow long the notification will stay on screen for in seconds.0.5f
heightfloatHeight notification will expand to if it has content other than a title. Default is 175.175
opacityfloatOpacity of the notification, to make it less intrusive. Setting to 0 will set to 1.1
volumefloatNotification sound volume.0.7f
audioPathstringFile path to .ogg audio file. Can be "default", "error", or "warning". Notification will be silent if left empty.""
titlestringNotification title, supports Rich Text Formatting.""
contentstringNotification content, supports Rich Text Formatting, if left empty, notification will be small.""
useBase64IconboolSet to true if using Base64 for the icon image.false
iconstringBase64 Encoded image, or file path to image. Can also be "default", "error", or "warning".""
sourceAppstringSomewhere to put your app name for debugging purposes.""
C#
void foobar()
{
    XSONotificationObject notification = new XSONotificationObject(); // See WebsocketAPI / XSONotificationObject for more information
    notification.title = "woah its an example!";
    notification.type = 1;
 
    XSOApiObject apiObject = new XSOApiObject(); // See WebsocketAPI / XSOApiObject for more information
    apiObject.sender = "xsoverlay";
    apiObject.target = target;
    apiObject.command = "SendNotification";
    apiObject.jsonData = JsonSerializer.Serialize(notification);
    apiObject.rawData = null;
 
    ws.Send(JsonSerializer.Serialize(apiObject));
}

RequestUpdateCursorCollisionTexture

Requests that the collision area for the panel be updated. Prevents cursor being visible on transparent parts of UI. May not update instantly.

C#
void foobar()
{
    ulong overlayHandle = 0; // See RequestOverlayIDs command for information about how to get your overlay handle.
 
    XSOApiObject apiObject = new XSOApiObject(); // See WebsocketAPI / XSOApiObject for more information
    apiObject.sender = "xsoverlay";
    apiObject.target = target;
    apiObject.command = "RequestUpdateCursorCollisionTexture";
    apiObject.jsonData = null;
    apiObject.rawData = overlayHandle;
 
    ws.Send(JsonSerializer.Serialize(apiObject));
}

RequestUpdateOverlayCanvasSize

Requests that the canvas resolution for the overlay be updated to the requested resolution. May not update instantly.

💡

You will not need to manually update cursor collision. This command will handle that for you once the texture resolution has been updated.

C#
void foobar()
{
    ulong overlayHandle = 0; // See RequestOverlayIDs command for information about how to get your overlay handle.
 
    XSOApiObject apiObject = new XSOApiObject(); // See WebsocketAPI / XSOApiObject for more information
    apiObject.sender = "xsoverlay";
    apiObject.target = target;
    apiObject.command = "RequestUpdateOverlayCanvasSize";
    apiObject.jsonData = "{
        "width": int,
        "height": int
    }";
    apiObject.rawData = overlayHandle;
 
    ws.Send(JsonSerializer.Serialize(apiObject));
}

SubscribeToEvents

Allows the application to subscribe to a set of tags that correspond to events that have return objects. See Subscribing to Events


Log

Logs a message to the output log.

Two Way Commands


RequestDateTime

Returns the current date and time, including session length, formatted based on User Setting

Return Object (JSON)
{
    "target" : "yourappname",
    "command": "UpdateDateTime",
    "jsonData": {
        "Date": string,
        "Time": string,
        "CurrentSessionLength": string
    }
}

RequestThemeUpdate

Returns the current theme colors in hexadecimal

Return Object (JSON)
{
    "target" : "yourappname",
    "command": "UpdateTheme",
    "jsonData": {
        "HiTone": string,
        "MidTone": string,
        "DarkTone": string,
        "ContrastingTone": string,
        "ErrorTone": string,
        "WarningTone": string,
        "ConfirmTone": string,
        "AccentColor": string,
        "AccentColorBright": string
    }
}

RequestSteamAvatar

Returns the steam avatar of the user

💡

This command uses the rawData field of XSOApiObject rather than the jsonData field.

Use

    XSOApiObject.target = "xsoverlay";
    XSOApiObject.command = "RequestSteamAvatar";
    XSOApiObject.rawData = "medium"; // can be large, medium, or small. defaults to medium if left empty
 
    WebsocketClient.Send(JsonSerializer.Serialize(XSOAbiObject));
Return Object (JSON)
{
    "target" : "yourappname",
    "command": "UpdateSteamAvatar",
    "jsonData": {},
    "rawData": string // Avatar image .png encoded in base64.
}

RequestDeviceInformation

Returns a list of devices and information about those devices

Return Object (JSON)
{
    "target" : "yourappname",
    "command": "UpdateDeviceInformation",
    "jsonData": {
        [
            {
                "id": int, // Device ID according to SteamVR
                "classification": int,
                "type": int,
                "lastUpdated": string, // ISO-8601 Time 
                "lastBatteryUpdate": string, // ISO-8601 Time 
                "connection": int, // connection status
                "charging": bool, // charging status
                "battery": float, // 0-100 battery life
                "label": string, // shorthand label
                "name": string, // SteamVR device name
                "timeEstimate": string, // estimated time remaining
                "runningBatterySecondsPerPercent": [ // How long in seconds it took for 1% battery to drain. Running list, contains last 5% drain.
                    float,
                    float,
                    float,
                    float,
                    float
                ],
                "runningBatteryIndex": int, // current index for the running list above.
                "fingerprint": string, // SteamVR unique fingerprint for the device. 
                "deviceDidPingLowBattery": bool, // has this device pinged low battery yet
                "friendlyName": string, // friendly name for the device. Not always used. 
                "waitingForFirstRealBatteryUpdate": bool 
            },
            // ... more devices ...
        ]
    }
}

RequestLayoutModeState

Returns the current open / closed state of Layout Mode

Return Object (JSON)
{
    "target" : "yourappname",
    "command": "UpdateLayoutModeState",
    "jsonData": {},
    "rawData": bool // bool representing state of layout mode.
}

RequestMediaPlayerUpdate

Returns the current media information

Return Object (JSON)
{
    "target" : "yourappname",
    "command": "UpdateMediaPlayer",
    "jsonData": {
        "artist": string,
        "title": string,
        "albumTitle": string,
        "albumArt": string, // Base64 string representing album art image.
        "playbackStatus": bool // bool represeting playback state
    }
}

RequestGetSettings

Returns user settings for the overlay

Return Object (JSON)
{
    "target" : "yourappname",
    "command": "UpdateSettings",
    "jsonData": {
          "AccentColor":  // Represents the theme accent color.
          {
                "r": float, // red
                "g": float, // green
                "b": float, // blue
                "a": float // No longer used.
          },
          "AdaptiveColor": float, // Represents how much mix the accent color into the primary theme color. This is between 0 and 1.
          "AimAtTarget": bool, // When enabled, this will aim the overlay at the target when holding it.
          "AimTarget": int, // Represents the target an overlay will aim at when holding it. This could be mixed (0), head (1), or hand (2). AimAtTarget must be enabled for this to work.
          "AllowAdminPermissions": bool, // When enabled, XSOverlay will be granted admin permissions.
          "AllowWristMovement": bool, // When enabled, this will allow the wrist overlay to be moved.
          "AlwaysShowDetailedInformation": bool, // When enabled, the wrist battery widget will always show battery percentage and time remaining.
          "AutoMediaDetection": bool, // When enabled, XSOverlay will automatically detect media playing.
          "AutoRecenter": bool, // When enabled, XSOverlay will automatically re-center when layout mode opens.
          "AutomaticMouseControl": bool, // When enabled, the mouse cursor automatically moves with the VR Cursor, or if an input is required first.
          "BatteryFontScale": int, // Represents the font-size for the battery widget.
          "BlockInputToBackgroundApplication": bool, // When enabled, XSOverlay will attempt to block input to the background application.
          "CaptureMethod": int, // Represents the capture method of the overlay. This is either Windows Game Capture (0) or BitBlt (1).
          "ContinentalTimeFormat": bool, // When enabled, the time format will be in 24 hour format.
          "CurvedOverlays": bool, // When enabled, this allows overlay windows to be curved.
          "DateFormat": int, // Represents the date format. This could be MM/DD/YYYY (0), DD/MM/YYYY (1).
          "DefaultShowBatteryPercentage": bool, // When enabled, the wrist battery widget will always show battery percentage instead of time remaining.
          "DiscordRichPresence": bool, // When enabled, XSOverlay will communicate to discord what you are playing.
          "DoubleClickDelay": float, // Represents the amount of time in milliseconds after a click that the cursor will freeze in place to allow for easier double-clicking.
          "DominantHand": int, // Dominant Hand. This would be left (0) or right (1).
          "ForceHigherQualityOverlays": bool, // When enabled, this will force overlays to be rendered at a higher resolution.
          "ForceJISKeyboard": bool, // When enabled, the keyboard is forced into JIS layout.
          "GrabSensitivity": float, // Represents the sensitivity of the grab gesture. This is between 0 (light) and 1 (hard).
          "HapticsStrength": float, // Represents the haptics strength when interacting with XSOverlay. This is between 0 and 1.
          "HideTooltips": bool, // When enabled, this hides tooltips.
          "HideWristOverlay": bool, // [Obsolete] This setting is no longer used. However, it is still here for backwards compatibility.
          "InputBlockingBehavior": int, // Represents the input blocking behavior. Chose between 'blocking when layout mode is open' (0) or 'blocking when hovering over an overlay' (1).
          "InputMethod": int, // Represents the input method of the cursor when interacting with devices. This would be touch (0) or mouse emulation (1).
          "InvertScaleGesture": bool, // When enabled, this will invert the scaling direction when scaling the overlay.
          "KeyboardFormat": int, // Format of the keyboard (minimal, half size, full).
          "KeyboardOpacity": float, // The opacity of the keyboard, between 0 and 1.
          "KeyboardSoundpackIndex": int, // Index to the currently loaded keyboard sound pack.
          "KeyboardSoundpackName": string, // Name of the currently loaded Keyboard sound pack.
          "KeyboardTypingSounds": bool, // When enabled, the keyboard typing noises are on.
          "Language": int, // Index of the currently selected language.
          "LanguageURL": string, // The path to the currently selected language on the system.
          "LowBatterySound": bool, // When enabled, XSOverlay will play a sound when the battery is low.
          "LowBatteryWarningPercent": int, // Represents the threshold of battery percentage that will trigger a low battery warning. This is between 0 and 100.
          "MediaThemeing": bool, // When enabled, XSOverlay will adjust the theme based on the playing media's album art.
          "NightLight": bool, // Represents the behavior of the night-light which can apply a red-ish hue to the overlays during select hours (true) or all time (false).
          "NightLightEndAMPM": bool, // When enabled, the night light cycle will end at PM, otherwise it will start at AM.
          "NightLightEndHour": int, // Represents the ending hour of the night light cycle.
          "NightLightIntensity": float, // Represents the intensity of the night light. This is between 0 and 1.
          "NightLightSchedule": bool, // When enabled, the night light will follow a schedule.
          "NightLightStartAMPM": bool, // When enabled, the night light cycle will start at PM, otherwise it will start at AM.
          "NightLightStartHour": int, // Represents the starting hour of the night light cycle.
          "NotificationOffsets": // Represents the notification offset relative to local space to the hmd.
          {
              "x": float,
              "y": float,
              "z": float
          }, 
          "NotificationScale": float, // Represents the notification scale. This is between 0 and 1.
          "OverlayClipAngle": int, // Represents the clip angle to auto-hide overlays when not looking at them. Auto-hide must be enabled for this to work.
          "OverlayCurveBias": float, // Represents the control strength of the overlay curving.
          "OverlayDefaultMaxFPS": int, // Represents the default maximum FPS of a newly created overlay overlay.
          "OverlayDefaultMinFPS": int, // Represents the default minimum FPS of a newly created overlay overlay.
          "OverlayDefaultOpacity": float, // Represents the default opacity of the overlay when it is created. This is between 0 and 1.
          "OverlayDefaultScale": float, // Represents the default scale of the overlay when it is created. This is between 0 and 1.
          "OverlayOpacity": float, // Represents the opacity of the overlay. This is between 0 and 1.
          "OverlayScale": float, // Represents the scale of the overlay. This is between 0 and 1.
          "PointerScale": float, // Represents the scale of the pointer. This is between 0 and 1.
          "PositionDampening": int, // Represents the reaction speed when an overlay adjusts its position when moving around. This is between 0 and 1.
          "PushSpeed": float, // Represents the speed of pushing/pulling an overlay. This is between 0 (slow) and 1 (fast).
          "RotationDampening": int, // Represents the reaction speed when an overlay adjusts its position when moving around. This is between 0 and 1.
          "ScaleSpeed": float, // Represents the speed of scaling an overlay. This is between 0 (slow) and 1 (fast).
          "SendAnalytics": bool, // When enabled, the anonymous analytics will be sent.
          "ShowWindowPreviews": bool, // [Obsolete] This setting is no longer used. However, it is still here for backward compatibility.
          "SmartRollAngle": int, // Represents the angle your head needs relative to the space overlay to adapt to being sideways. (I.E. For Laying down).
          "UUID": string, // UUID of the user. This is an anonymous identifier used for analytics.
          "UseDarkTheme": bool, // When enabled, XSOverlay will use the dark theme.
          "VersionNumber": int, // Version Number.
          "WristClipAngle": int, // Represents the clip angle to auto-hide the wrist overlay when not looking at it.
          "WristOffsets": // Represents the wrist overlay position in local space. This is relative to the device it's attached to.
          {
              "x": float, // X Positional offset
              "y": float, // Y Positional offset
              "z": float  // Z Positional offset
          },
          "WristOpacity": float, // Represents the opacity of the wrist overlay. This is between 0 and 1.
          "WristRotation":// Represents the wrist overlay rotation, in euler angles, in local space. This is relative to the device it's attached to.
          { 
                "x": float, // X Euler Rotation
                "y": float, // Y Euler Rotation
                "z": float  // Z Euler Rotation
          }, 
          "WristScale": float // Wrist overlay scale.
        }
    }
}

RequestUpdatedLanguageList

Returns the list of possible languages

Return Object (JSON)
{
    "target" : "yourappname",
    "command": "UpdateLanguageList",
    "jsonData": {
        "LanguageName": string,
        "LanguageName2": string,
        // ... more languages ...
    }
}

RequestUpdatedLanguageMap

Returns the map of strings for the currently selected language

Return Object (JSON)
{
    "target" : "yourappname",
    "command": "UpdateLanguageMap",
    "jsonData": {
        // Key value map that XSO uses to translate languages.
        // Please look at translation files for the list of strings.
    }
}

RequestAchievementInformation

Returns list of achievements with a boolean for unlocked / locked for the user.

Return Object (JSON)
{
    "target" : "yourappname",
    "command": "UpdateAchievementStatus",
    "jsonData": {
        "ACHIEVEMENT_NAME": bool,
        "ACHIEVEMENT_NAME_1": bool,
        "ACHIEVEMENT_NAME_2": bool,
    }
}

RequestWindowList

Returns a list of windows that can be captured.

Return Object (JSON)
{
    "target" : "yourappname",
    "command": "UpdateWindowList",
    "jsonData": {
          "0": {
                "id": int,
                "title": string,
                "icon": string, // base64 icon image
                "windowPreview": string, // base64 preview image. Currently not used.
                "appName": string,
                "isDesktop": bool,
                "isPrimaryDesktop": bool,
                "isUWP": bool,
                "isSystem": bool
            }
            // ... more entries ...
    }
}

RequestActiveOverlayInformation

Requests the current active overlay. This is the overlay that has ownership of the window toolbar

Return Object (JSON)
{
    "target" : "yourappname",
    "command": "UpdateActiveOverlayInformation",
    "jsonData": {
        "0": {
            "id": int,
            "title": string,
            "icon": string, // base64 icon image
            "windowPreview": string, // base64 preview image. Currently not used.
            "appName": string,
            "isDesktop": bool,
            "isPrimaryDesktop": bool,
            "isUWP": bool,
            "isSystem": bool
        }
        // ... more entries ...
    }
}

RequestRuntimePerformance

Requests information about system resource usage, such as CPU, GPU, and Memory.

Hardware Type / Manufacturer IDs
const HardwareType = {
    Generic: 0,
    Gpu: 1,
    Cpu: 2,
    Memory: 3
}
 
const HardwareManufacturer = {
    Nvidia: 0,
    Amd: 1,
    Intel: 2,
    Generic: 3
}
Return Object (JSON)
{
    "target" : "yourappname",
    "command": "UpdateRuntimePerformance",
    "jsonData": {
        "CPU": {
            "Type": int,
            "Manufacturer": int,
            "Name": string,
            "Temperature": float,
            "Load": float, // Used for device utilization, e.g. GPU / CPU Usage.
            "MemLoad": float, // Used for memory utilization, like VRAM / RAM.
            "MemSize": float
        },
        "GPU": {
            "Type": int,
            "Manufacturer": int,
            "Name": string,
            "Temperature": float,
            "Load": float, // Used for device utilization, e.g. GPU / CPU Usage.
            "MemLoad": float, // Used for memory utilization, like VRAM / RAM.
            "MemSize": float
        },
        "Memory": {
            "Type": int,
            "Manufacturer": int,
            "Name": string,
            "Temperature": float,
            "Load": float, // Used for device utilization, e.g. GPU / CPU Usage.
            "MemLoad": float, // Used for memory utilization, like VRAM / RAM.
            "MemSize": float
        },
        "Frametime": float, // Current time in ms between the previous frame and this frame.
        "Framerate": float, // Current framerate in Frames Per Second
        "MaxFrametime": float, // Maximum frametime based on Headset Refresh Rate in ms e.g. 90hz = 11.1ms
        "MaxFramerate": float // Equal to HMD Refresh Rate
    }
}

RequestOverlayIDs

Sometimes, you might want to change something about the overlay that you are currently rendering on, or about another overlay that exists in the OpenVR scene. This command will allow you to do that by getting a map back which allows you to reference the overlay by it's handle with further commands.

If you are a webapp and have an overlay, to figure out which overlay handle you're rendering on, just access the jsonData property as an array with your URL location.

Example.js
Api.Client.Socket.addEventListener('message', function message(data) {
   var decoded = Api.Parse(data);
    switch (decoded.Command) {
        case 'UpdateOverlayIDs':
            console.log(`Current Overlay ID for ${window.location.href} : ${decoded.JsonData[window.location.href]}`);
            break;
    }
});
Return Object (JSON)
{
    "target" : "yourappname",
    "command": "UpdateOverlayIDs",
    "jsonData": {
        "overlayPageURL" : ulong,
        "anotherOverlayPageURL" : ulong
        // ... more entries ...
    }
}