Robotics client per (tenant, robot). Then you open scoped publications
and subscriptions. The client holds a single MoQT session and connects
lazily on the first call. It reconnects automatically and replays every
publication and subscription on reconnect. Your code does nothing on a link
flap.
Import
Construct a client
RoboticsOptions
string
required
Relay host or full URL:
"relay.clutchcall.dev" or
"https://relay.clutchcall.dev". Every namespace derives from it.string
required
The robot that this client speaks for. The SDK uses it to build
robot/<id> (telemetry) and robot/<id>/ctl (commands).string
Bearer token for the relay session, scoped to
(tenant, robotId).string
Base64 SHA-256 of the relay’s cert, for pinned WebTransport in the browser.
WebTransportFactory
Inject a custom WebTransport factory (Node polyfill / tests).
(e: Error) => void
The SDK calls this when the underlying relay session closes with an error.
Methods
publishTelemetry(spec)
Open a robot → cloud track under robot/<id>. Returns a
RoboticsPublication.
string
required
Track name under the telemetry namespace, for example
"odom",
"battery_state".string
required
Full ROS 2 message type, for example
"nav_msgs/msg/Odometry". The SDK
prefixes it on the wire.QoS
QoS profile (below). Omit for the best-effort default.
publishCommand(spec)
Open a cloud → robot track under robot/<id>/ctl. The spec shape is the
same as publishTelemetry. Returns a RoboticsPublication.
subscribeTelemetry(spec, onMessage)
Receive robot → cloud frames from robot/<id>. The callback gets the raw
CDR payload and the wire type name. Use the type name to check and route
messages.
string
required
Track name to subscribe under the telemetry namespace.
(cdr: Uint8Array, typeName: string) => void
required
The SDK invokes this for each delivered message.
cdr is the opaque
payload. typeName is the prefix decoded from the wire.subscribeCommand(spec, onMessage)
Receive cloud → robot frames from robot/<id>/ctl. The shape is the same as
subscribeTelemetry. The robot (or the on-robot bridge) makes this call to
receive teleop commands.
close()
Close the underlying MoQT session and all publications / subscriptions. The
call is idempotent.
Handles
RoboticsPublication
Returned by publishTelemetry / publishCommand.
method
Send one typed message.
cdr is the raw CDR (or the bytes that match your
typeName). The SDK prepends the type-name prefix and opens a fresh MoQT
group per message. priority (TypeScript) overrides the QoS default for
this single frame: 0 highest, 255 lowest. The call returns immediately.
The MoQT layer handles ordering and reliability.method
Stop publishing this track.
RoboticsSubscription (TypeScript)
subscribeTelemetry / subscribeCommand resolve when the subscription is
attached. In the TypeScript SDK, the resolved handle exposes close() to
stop receiving. In Python / Go, the returned subscription object exposes the
same method.
QoS profile
The default profile matches ROS 2’s
SensorDataQoS (best-effort, volatile,
keep-last). See Details → QoS → lanes for the
full capability mapping.
Events & lifecycle
- Connection state — the client shows the relay session lifecycle
(
Connecting · Connected · Reconnecting · Closed · Failed). In TypeScript, passonStatevia the underlying options. In other SDKs, the connect callback reports state codes. Auto-reconnect with capped backoff re-attaches every track on its own. - Late join — a subscriber that joins after a publisher immediately
receives the relay’s retained group window (sized by
depth, latched bytransient_local). - Errors —
onError(TypeScript) fires on relay close with a reason string. Individual publish/subscribe calls reject if the session cannot be established.

