Short, copy-pasteable answers to “how do I X” for the robotics modality. Each assumes a constructed client:
import { Robotics } from "@clutchcall/sdk/robotics";

const r = new Robotics({
  relayHost: "relay.clutchcall.dev",
  robotId:   "spot-12",
  token:     process.env.CLUTCHCALL_CREDENTIALS!,
});

Publish a telemetry stream

Open one track per topic and write raw CDR. Best-effort by default — perfect for high-rate pose / odometry where the freshest sample wins.
const odom = await r.publishTelemetry({
  topic:    "odom",
  typeName: "nav_msgs/msg/Odometry",
});
setInterval(() => odom.write(serializeOdom()), 50); // 20 Hz

Send a teleop command

Commands go cloud → robot on robot/<id>/ctl. Use the reliable lane so a stop or a goal can’t be dropped.
const cmd = await r.publishCommand({
  topic:    "cmd_vel",
  typeName: "geometry_msgs/msg/Twist",
  qos:      { reliability: "reliable" },
});
cmd.write(twistCdr(0.4 /* m/s */, 0.0 /* rad/s */));

Subscribe to a robot’s telemetry from the cloud

The callback receives the raw CDR and the wire type name. Guard on the type name before decoding.
await r.subscribeTelemetry({ topic: "odom" }, (cdr, typeName) => {
  if (typeName !== "nav_msgs/msg/Odometry") return;
  const { x, y } = decodeOdom(cdr);
  dashboard.plot(x, y);
});

Have the robot receive commands

On the robot (or the on-robot bridge), subscribe the command track and apply each message to the local actuator stack.
await r.subscribeCommand({ topic: "cmd_vel" }, (cdr) => applyTwist(cdr));

Pick the right QoS lane

Reliable for things that must arrive (commands, maps, goals); best-effort for high-rate sensors where latency beats completeness.
// must-arrive map update → subgroup stream, ordered
await r.publishTelemetry({ topic: "map", typeName: "nav_msgs/msg/OccupancyGrid",
  qos: { reliability: "reliable" } });

// 30 Hz LIDAR scan → QUIC datagram, lossy, lowest latency
await r.publishTelemetry({ topic: "scan", typeName: "sensor_msgs/msg/LaserScan",
  qos: { reliability: "best_effort", depth: 1 } });

Latch a value for late subscribers

transient_local makes the relay retain the last group(s), so a dashboard that connects later immediately gets the current value — like a latched / retained message.
const state = await r.publishTelemetry({
  topic:    "robot_state",
  typeName: "std_msgs/msg/String",
  qos:      { durability: "transient_local", reliability: "reliable", depth: 1 },
});
state.write(encode("idle")); // a future subscriber sees "idle" on join

Override priority per message

The QoS reliability sets a default send priority; override it on a single write to push an urgent frame ahead of the queue (0 highest, 255 lowest).
const cmd = await r.publishCommand({ topic: "cmd_vel", typeName: "geometry_msgs/msg/Twist" });
cmd.write(normalTwist);            // default priority for the lane
cmd.write(emergencyStop(), 0);     // jump the queue

Demux across languages

The type-name prefix means a Python publisher and a TypeScript subscriber agree with no schema registry. Publish from Python:
from clutchcall.robotics import Robotics
r = Robotics(relay_host="relay.clutchcall.dev", robot_id="spot-12", token=tok)
pub = r.publish_telemetry(topic="odom", type_name="nav_msgs/msg/Odometry")
pub.write(serialize_message(msg))   # raw CDR
…and the TypeScript dashboard above receives ("nav_msgs/msg/Odometry", cdr) unchanged.

Fan multiple topics into one dashboard

One client, many subscriptions — they all ride the single QUIC session.
for (const t of ["odom", "battery_state", "scan"]) {
  await r.subscribeTelemetry({ topic: t }, (cdr, typeName) => ingest(t, typeName, cdr));
}

Subscribe to many robots from one process

Construct one client per robot; each opens its own session and namespace.
const fleet = ["spot-12", "spot-13", "spot-14"].map(id =>
  new Robotics({ relayHost: "relay.clutchcall.dev", robotId: id, token }));

await Promise.all(fleet.map(c =>
  c.subscribeTelemetry({ topic: "battery_state" }, (cdr) => trackBattery(cdr))));

Bridge a local ROS 2 topic onto the mesh

Subscribe the local graph, forward raw CDR to a telemetry track. Below in Python with rclpy serialization:
from rclpy.serialization import serialize_message
pub = r.publish_telemetry(topic="odom", type_name="nav_msgs/msg/Odometry")
node.create_subscription(Odometry, "/odom", lambda m: pub.write(serialize_message(m)), 10)

Bridge a command back onto the local graph

The other direction: subscribe the MoQT command track, re-publish onto local DDS. Guard on type name so schema drift is dropped, not mis-decoded.
from rclpy.serialization import deserialize_message
cmd_pub = node.create_publisher(Twist, "/cmd_vel", 10)
def on_cmd(cdr, type_name):
    if type_name == "geometry_msgs/msg/Twist":
        cmd_pub.publish(deserialize_message(cdr, Twist))
r.subscribe_command(topic="cmd_vel", on_message=on_cmd)

Tune the late-join window

depth caps how many recent groups the relay holds for a late subscriber — mirror your ROS 2 keep-last history.
await r.publishTelemetry({ topic: "tf", typeName: "tf2_msgs/msg/TFMessage",
  qos: { reliability: "reliable", depth: 50 } });

Shut down cleanly

Close publications and subscriptions, then the client — this tears down the QUIC session.
odom.close();
r.close();