HTTP
By default, the HTTP service starts on: http://localhost:10001.
The port can be changed in the service's configuration.
Overview
This section documents the HTTP routes exposed by the service.
All routes below assume the default base URL: http://localhost:10001.
Standard response envelope
All endpoints return one of two envelopes:
No-data response (used by mutation-only endpoints):
{ "ok": true }
{ "ok": false, "error": "reason string" }
Data response (used by GET, and by POST/DELETE on config endpoints that echo the applied value):
{ "ok": true, "data": { "..." : "..." } }
{ "ok": false, "error": "reason string" }
Device selector syntax
Device-level routes use the pattern /{device_type}/{id_or_index}/.... The {device_type} and {id_or_index} path segments identify the target device(s).
| Example path segment | Meaning |
|---|---|
inverse3/0 | First Inverse3 by index (0-based) |
inverse3/A14 | Inverse3 with device ID A14 |
inverse3/* | All Inverse3 devices (wildcard) |
verse_grip/0 | First Verse Grip by index |
wireless_verse_grip/* | All Wireless Verse Grips |
*inverse/* | All Inverse-family devices (Inverse3, Inverse3x, Minverse) |
*verse_grip/* | All Verse Grip-family devices (Verse Grip, Wireless VG) |
Wildcard rules:
GETrejects ambiguous/wildcard selectors (returns400).POSTandDELETEaccept wildcards -- the operation is applied to all matching devices.
Session selector
Session-scoped endpoints (basis, mount, preset, transform, filters) require a ?session=<expr> query parameter to identify the session.
| Expression | Meaning |
|---|---|
| (omitted) | All sessions (DELETE only) |
#123 or 123 | Session with numeric ID 123 |
:-1 | Last session by index |
:0 | First session by index |
Example: GET /inverse3/0/config/basis?session=:0
Version
Method: GET
URL: http://localhost:10001/version
Response example:
{
"build_time": "2024-08-07T16:01:53Z",
"git_branch": "main",
"git_describe": "3.5.0-2-gce34c39e",
"git_hash": "ce34c39e",
"git_tag": "3.5.0",
"project_name": "haply-inverse-service",
"project_version": "3.5.0"
}
Expert Status
Method: GET
URL: http://localhost:10001/expert/status
Returns detailed status information including detection, devices, sessions, and global settings.
Devices
Method: GET
URL: http://localhost:10001/devices
Returns the current device inventory, including config, state, and status.
You can optionally pass ?session=<expr> to filter the snapshot to a specific session's perspective (applies that session's basis, mount, and transforms to the returned values).
Response example:
{
"inverse3": [
{
"device_id": "04BA",
"config": { "...": "..." },
"state": { "...": "..." },
"status": { "...": "..." }
}
]
}
Sessions
| Method | Path | Description |
|---|---|---|
| GET | /sessions | List all active v3.1 sessions |
| GET | /sessions/{session_id} | Get a single session |
| GET | /sessions/{session_id}/profile | Get session profile name |
| POST | /sessions/{session_id}/profile | Set session profile |
| DELETE | /sessions/{session_id}/profile | Reset profile to "default" |
POST /sessions/{session_id}/profile body:
{
"name": "my_profile"
}
Ports
Method: POST
URL: http://localhost:10001/ports/{port}/reset
Clears a blocked serial port. Returns { "ok": true }.
Device Configuration
All config endpoints use the pattern /{device_type}/{id_or_index}/config/{setting}.
Session-scoped endpoints (basis, mount, preset) additionally require a ?session=<expr> query parameter.
Handedness (Inverse3 only)
| Method | Path | Body | Response |
|---|---|---|---|
| GET | /{device_type}/{id}/config/handedness | -- | "left" or "right" |
| POST | /{device_type}/{id}/config/handedness | "left" or "right" | echoed value |
| DELETE | /{device_type}/{id}/config/handedness | -- | "right" (default) |
Torque Scaling (Inverse3 only)
| Method | Path | Body | Response |
|---|---|---|---|
| GET | /{device_type}/{id}/config/torque_scaling | -- | { "enabled": bool } |
| POST | /{device_type}/{id}/config/torque_scaling | { "enabled": bool } | echoed value |
| DELETE | /{device_type}/{id}/config/torque_scaling | -- | { "enabled": false } |
Gravity Compensation (Inverse3 only)
| Method | Path | Body | Response |
|---|---|---|---|
| GET | /{device_type}/{id}/config/gravity_compensation | -- | { "enabled": bool, "scaling_factor": float } |
| POST | /{device_type}/{id}/config/gravity_compensation | { "enabled": bool, "scaling_factor": float } | echoed value |
| DELETE | /{device_type}/{id}/config/gravity_compensation | -- | { "enabled": true, "scaling_factor": 1.0 } |
Basis (all devices, session-scoped)
| Method | Path | Body | Response |
|---|---|---|---|
| GET | /{device_type}/{id}/config/basis?session= | -- | { "permutation": "XYZ" } |
| POST | /{device_type}/{id}/config/basis?session= | { "permutation": "ZXY" } | echoed value |
| DELETE | /{device_type}/{id}/config/basis?session= | -- | { "permutation": "XYZ" } |
Mount (all devices, session-scoped)
| Method | Path | Body | Response |
|---|---|---|---|
| GET | /{device_type}/{id}/config/mount?session= | -- | { "transform": {...} } |
| POST | /{device_type}/{id}/config/mount?session= | { "transform": {...} } | echoed value |
| DELETE | /{device_type}/{id}/config/mount?session= | -- | identity transform |
Transform shape (used by mount and state/transform):
{
"transform": {
"position": { "x": 0, "y": 0, "z": 0 },
"rotation": { "x": 0, "y": 0, "z": 0, "w": 1 },
"scale": { "x": 1, "y": 1, "z": 1 }
}
}
Preset (all devices, session-scoped)
| Method | Path | Body | Response |
|---|---|---|---|
| GET | /{device_type}/{id}/config/preset?session= | -- | { "preset": "arm_front_centered" } |
| POST | /{device_type}/{id}/config/preset?session= | { "preset": "arm_front_centered" } | echoed value |
| DELETE | /{device_type}/{id}/config/preset?session= | -- | { "preset": "device_defaults" } |
Available values: device_defaults, arm_front, arm_front_centered, led_front, led_front_centered, custom.
Device Filters (Inverse3 only, session-scoped)
Filter endpoints use /{device_type}/{id}/config/filters/{filter}?session=<expr>.
Damping
Controls both uniform and directional damping. At least one field must be present in POST body.
| Method | Path | Body | Response |
|---|---|---|---|
| GET | /{device_type}/{id}/config/filters/damping?session= | -- | { "scalar": float, "vector": { "x": f, "y": f, "z": f } } |
| POST | /{device_type}/{id}/config/filters/damping?session= | { "scalar": float } or { "vector": {...} } or both | echoed values |
| DELETE | /{device_type}/{id}/config/filters/damping?session= | -- | both reset to zero |
Force Gate
| Method | Path | Body | Response |
|---|---|---|---|
| GET | /{device_type}/{id}/config/filters/force_gate?session= | -- | { "gain": float } |
| POST | /{device_type}/{id}/config/filters/force_gate?session= | { "gain": float } | echoed value |
| DELETE | /{device_type}/{id}/config/filters/force_gate?session= | -- | gain from settings default |
Device State
Transform (all devices, session-scoped)
Workspace transform (device-space to application-space).
| Method | Path | Body | Response |
|---|---|---|---|
| GET | /{device_type}/{id}/state/transform?session= | -- | { "transform": {...} } |
| POST | /{device_type}/{id}/state/transform?session= | { "transform": {...} } | echoed value |
| DELETE | /{device_type}/{id}/state/transform?session= | -- | identity transform |
Save Configuration
Only works with Inverse3 devices. Warning: Avoid saving the configuration too often, since there is a limited number of saves that can be applied to any given device (~10,000 EEPROM writes).
Method: POST
URL: http://localhost:10001/save_configuration
Body example:
{
"device_id": "049D"
}
Response example:
{
"ok": true
}
Settings
Settings endpoints are auto-generated for:
- Listing all settings (including metadata)
- Reading a single setting value
- Applying settings (single or batch)
- Resetting a key to its default value
All settings key references can be found here
Routes
| Method | Route | Description |
|---|---|---|
| GET | /settings/ | Get all settings keys, values, and metadata. |
| POST | /settings/ | Batch apply multiple settings at once. |
| GET | /settings/{key} | Get the current value of a specific setting key. |
| POST | /settings/{key} | Apply a new value to a specific key. |
| DELETE | /settings/{key} | Reset a key to its default value. |
Response shape
GET /settings/ (all settings)
Returns an object keyed by setting key. Each entry includes:
value: the current valuemetadata: type + constraints + lock state
Example entries:
{
"devices/detection/timeout": {
"metadata": {
"constraint": {
"range": {
"max": 15,
"min": 1,
"step": 0
}
},
"locked": false,
"type_hint": "INT"
},
"value": 5
}
}
GET /settings/{key} (single setting)
Returns only the value (no metadata) for the requested key.
Applying settings
POST /settings/ (batch apply)
Batch apply multiple keys at once.
Suggested body format: a JSON object mapping keys to values.
{
"devices/detection/timeout": 5,
"devices/detection/advanced/wvg_description_filter": ["Haply USB Transceiver", "Haply Handle"]
}
POST /settings/{key} (single apply)
Apply a new value to a single key.
Suggested body format: either a raw JSON value or a wrapped value (prefer wrapping for clarity).
{
"value": 5
}
Resetting settings
DELETE /settings/{key}
Resets the key back to its default value.
This is equivalent to "reset to default".
Type hints
The service deduces type_hint automatically. GENERIC is used as a fallback for complex types.
Supported hints:
BOOLINTFLOATSTRINGVEC2VEC3VEC4TRANSFORMARR_INTARR_FLOATARR_STRINGGENERIC
Deprecated Legacy Endpoints
Several POST endpoints are still accepted but emit a deprecation warning
and will be removed in 4.0. See the 3.5 migration guide
for the full deprecated-path → replacement-route table.