Connect to a machine | Common tasks

Connect to a machine

Open a connection to a single Viam machine from your app, structure the connection code so you do not reconnect unnecessarily, and close the connection when the app is done with it. This page covers the basic connection pattern. For reconnection, UI indicators, and connection-state events, see Handle disconnection and reconnection. For apps that access multiple machines or the fleet APIs, see Connect to the Viam cloud.

Prerequisites

Open a connection

import * as VIAM from "@viamrobotics/sdk";

const machine = await VIAM.createRobotClient({
  host: "my-robot-main.xxxx.viam.cloud",
  credentials: {
    type: "api-key",
    authEntity: "<API-KEY-ID>",
    payload: "<API-KEY>",
  },
  signalingAddress: "https://app.viam.com:443",
});

createRobotClient returns a RobotClient connected to your machine. The await resolves once the WebRTC connection is established and the session has started.

import 'package:viam_sdk/viam_sdk.dart';

final robot = await RobotClient.atAddress(
  'my-robot-main.xxxx.viam.cloud',
  RobotClientOptions.withApiKey('your-api-key-id', 'your-api-key-secret'),
);

RobotClient.atAddress returns a RobotClient connected to your machine. The await resolves once the WebRTC connection is established and the session has started.

import asyncio
from viam.robot.client import RobotClient

async def connect():
    opts = RobotClient.Options.with_api_key(
        api_key='your-api-key-secret',
        api_key_id='your-api-key-id'
    )
    return await RobotClient.at_address('my-robot-main.xxxx.viam.cloud', opts)

machine = await connect()

RobotClient.at_address is async. All Viam Python SDK methods use async/await and run inside asyncio.run().

import (
    "context"
    "go.viam.com/rdk/logging"
    "go.viam.com/rdk/robot/client"
)

logger := logging.NewDebugLogger("client")
machine, err := client.New(
    context.Background(),
    "my-robot-main.xxxx.viam.cloud",
    logger,
    client.WithDialOptions(client.WithEntityCredentials(
        "your-api-key-id",
        client.Credentials{
            Type:    client.CredentialsTypeAPIKey,
            Payload: "your-api-key-secret",
        },
    )),
)
if err != nil {
    logger.Fatal(err)
}

client.New returns a *RobotClient and an error. Always check the error before using the client.

For an explanation of what the SDK does during connection (WebRTC signaling, ICE, sessions, reconnection), see Connection model. The defaults work for machines deployed on Viam Cloud; you override them only for self-hosted or local-network setups.

Close the connection

Close the connection when your app is done with it. Closing releases resources, ends the session, and stops background reconnection attempts.

await machine.disconnect();
await robot.close();
await machine.close()
machine.Close(context.Background())

In a browser app, the tab closing eventually tears down the connection on its own, but closing explicitly avoids a race where pending operations continue after the page unloads. In a Node.js script, always close before process.exit() or the script may hang on an open WebRTC connection. In a Flutter app, close in State.dispose() if the connection was created per-screen, or in a service class’s dispose method if the connection is app-wide.

Handle errors during connect

Network failures, wrong credentials, and unreachable machines all raise errors from the connect call. Wrap the call in a try-catch:

let machine: VIAM.RobotClient;
try {
  machine = await VIAM.createRobotClient({
    host: "my-robot-main.xxxx.viam.cloud",
    credentials: {
      type: "api-key",
      authEntity: "<API-KEY-ID>",
      payload: "<API-KEY>",
    },
    signalingAddress: "https://app.viam.com:443",
  });
} catch (err) {
  console.error("Failed to connect:", err);
  return;
}
late RobotClient robot;
try {
  robot = await RobotClient.atAddress(
    'my-robot-main.xxxx.viam.cloud',
    RobotClientOptions.withApiKey('your-api-key-id', 'your-api-key-secret'),
  );
} catch (e) {
  print('Failed to connect: $e');
  return;
}

machine, err := client.New(
    context.Background(),
    "my-robot-main.xxxx.viam.cloud",
    logger,
    client.WithDialOptions(client.WithEntityCredentials(
        "your-api-key-id",
        client.Credentials{
            Type:    client.CredentialsTypeAPIKey,
            Payload: "your-api-key-secret",
        },
    )),
)
if err != nil {
    logger.Fatalf("Failed to connect: %v", err)
}
def defer machine.Close(context.Background())

The error from a failed connect is generic. The SDK does not always distinguish credential errors from network errors. Log the error message verbatim when debugging, and check the CONNECT tab in the Viam app to confirm the machine is online before assuming the code is wrong.

Once the connection is established, subsequent network drops trigger automatic reconnection rather than thrown errors. See Handle disconnection and reconnection for the reconnection pattern.

Where to put connection code

Create the RobotClient once at the right lifetime boundary and share it across the parts of your app that need it. Do not call createRobotClient or RobotClient.atAddress inside a render function or a click handler: each call opens a new connection and orphans the previous one.

Next