Getting started
Take your first steps with the Teslasuit C API — from linking the SDK to running your first haptic interaction.
Requirements#
| Requirement | Version |
|---|---|
| Teslasuit hardware | v. 4.5+ |
| Teslasuit SDK | 2.5.1+ |
| C compiler | C11-capable — MSVC 2019+, GCC 9+, or Clang 10+ |
Link the SDK#
1. Get the headers and library#
The SDK ships with Teslasuit Studio, so make sure it is installed and on the desired target version. You can find the C API headers in the TESLASUIT_API_LIB_PATH location, typically C:\Program Files\Teslasuit\Studio\include.
You can either copy the headers into your project to link them at build time, or resolve the library by path at runtime. The documentation examples will use the latter approach.
2. Load the library and resolve the functions you need#
For ease of use, the examples in these docs open the shared library at runtime rather than linking against teslasuit_api at build time. As such, each function needs a matching function-pointer typedef, since there's no import library to link against:
#include <ts_api/ts_core_api.h>
typedef TsStatusCode (*ts_initialize_func_t)(void);
static ts_initialize_func_t ts_initialize;
const char *api_path = getenv("TESLASUIT_API_LIB_PATH");
void *lib = dlopen(api_path, RTLD_NOW | RTLD_LOCAL); // LoadLibraryEx on Windows
ts_initialize = (ts_initialize_func_t)dlsym(
lib, "ts_initialize"); // GetProcAddress on WindowsDoing this by hand for every function gets repetitive fast. For simplicity, the examples in Examples define the macros DECLARE_API_FUNCTION and LOAD_API_FUNCTION as a ready-to-copy starting point.
#define API_FUNCTION_NAME(name) name##_func_t
#define DECLARE_API_FUNCTION(ret, name, args) \
typedef ret(*API_FUNCTION_NAME(name)) args; \
static API_FUNCTION_NAME(name) name
#define LOAD_API_FUNCTION(lib, name) \
do { \
name = (API_FUNCTION_NAME(name))api_library_get_function(lib, #name); \
if (name == NULL) \
return false; \
} while (0)Configure the native library path#
The Teslasuit C API relies on the native teslasuit_api.dll that ships with Teslasuit Studio. Studio normally registers it in your system environment variables on install, so no setup is required and the following approach can be used reliably:
const char *api_path = getenv("TESLASUIT_API_LIB_PATH");
if (api_path == NULL) {
printf("Error: environment variable TESLASUIT_API_LIB_PATH not set\n");
return 0;
}
SharedLibrary lib =
(SharedLibrary)LoadLibraryEx(api_path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
if (lib == NULL) {
printf("Error: library was not found\n");
return 0;
}If the load fails, then the variable was not set (common on non-admin installs) or was set incorrectly. Fix it with either option.
Set the variables yourself#
User-level, so no admin is needed; restart any open terminals afterwards:
[Environment]::SetEnvironmentVariable("TESLASUIT_API_LIB_PATH", "C:\Program Files\Teslasuit\Studio\teslasuit_api.dll", "User")
[Environment]::SetEnvironmentVariable("TESLASUIT_INSTALL_DIR", "C:\Program Files\Teslasuit\Studio", "User")
[Environment]::SetEnvironmentVariable("TESLASUIT_PYTHON_API_PATH", "C:\Program Files\Teslasuit\Studio\python_api", "User")
Or pass the path in code#
const char *api_path = "path/to/teslasuit_api.dll";
SharedLibrary lib =
(SharedLibrary)LoadLibraryEx(api_path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
if (lib == NULL) {
printf("Error: library was not found\n");
return 0;
}No environment changes needed, and it also covers a non-default install location: just point lib_path at teslasuit_api.dll. Note that this hardcodes a machine-specific path into your script, so it is less portable; prefer the environment variables for code you share or run across setups.
Connect to a device#
The snippets below call functions like ts_initialize() directly, for readability. In real code each one is a resolved function pointer, as shown above — see any page under Examples for complete, compilable examples with the loader included.
Device connection is managed by Teslasuit Control Center (CC), not by your C program. The C API can only reach a device that is already connected and active in Control Center — there is no way to initiate or maintain a connection from code alone.
Before running any C program:
- Open Teslasuit Control Center.
- Connect your device and wait for it to appear as active.
- Complete the calibration procedure in Control Center. Subsystems such as haptic and mocap will not produce correct output on an uncalibrated device.
Once the device is connected and calibrated in Control Center, the C API can discover it:
#include <ts_api/ts_core_api.h>
#include <ts_api/ts_device_api.h>
int main(void) {
// Initialize using the default session data storage directory
ts_initialize();
// Initialize using a custom session data storage directory
// Useful if the default directory isn't writeable or for session isolation
// ts_initialize_with_path("/custom/data/dir");
// Poll until a device is attached (Control Center owns the connection).
TsDevice device;
uint32_t device_count = 0;
while (device_count == 0) {
device_count = 1;
ts_get_device_list(&device, &device_count);
}
TsDeviceHandle *dev = ts_device_open(&device);
printf("Connected: %s\n", ts_device_get_name(dev));
// ... use dev with the haptic / mocap / biometry APIs ...
ts_device_close(dev);
ts_uninitialize();
return 0;
}Every C API call returns a TsStatusCode (Good on success) — check it after every call in real code. See ts_get_status_code_message for turning a code into a human-readable string.
Access a subsystem#
Every subsystem is a plain function that takes the TsDeviceHandle* as its first argument:
#include <ts_api/ts_biometry_api.h>
#include <ts_api/ts_haptic_api.h>
#include <ts_api/ts_mocap_api.h>
ts_haptic_stop_player(dev); // haptic
ts_mocap_start_streaming(dev); // mocap
ts_ppg_start_streaming(dev); // biometry (PPG)Next#
Once you have a connected device, here is a suggested reading flow through the rest of the documentation.
1. Run something end-to-end — Examples#
Get a feel for the API by running a complete, minimal program on real hardware:
- Examples · Overview — every runnable example, grouped by subsystem.
- Play a haptic touch — play your first touch on the suit.
- Read heart rate — read live heart rate from a PPG node.
- Measure HRV — read the Mean inter-beat interval, a heart rate variability (HRV) metric, from the PPG sensor.
- Stream motion data — stream skeleton data and biomechanical angles.
2. Understand what you just ran — Main concepts#
Each subsystem has a concept page that explains what it senses or does, and the vocabulary the rest of the reference assumes:
- Main concepts · Overview — a map of the XR5 subsystems with a per-topic reading list.
- Haptics & EMS — programmable electrical stimulation.
- Mocap — full-body motion capture.
- PPG — optical heart-rate sensing.
- Body & channel map — a Python-first interactive tool showing how bones resolve to physical channels; conceptually the same resolution the C mapping API performs.
3. Look things up — API reference#
When you know what you want to build, the reference covers the SDK class by class. It is split into two layers:
API · Core — the layer above subsystems (connecting devices, mapping, shared types):
- Common Types — the structs, enums and type aliases used across every module.
- Core API — library init/uninit and version info.
- Device API — discover, open, and close devices.
- Mapping API — resolve a bone to its physical channels.
- Asset API — load and manage haptic assets.
API · Subsystems — one header per device capability:
- Haptic API — create, play and control haptic touches and playables.
- Mocap API — stream raw IMU, skeleton and biomechanical data.
- Biometry API — PPG, HRV, EMG, BIA and current-feedback sensing.
