Connect to the Viam cloud | Common tasks

Connect to the Viam cloud

Open a connection to the Viam cloud to access the fleet, data, ML training, billing, and provisioning APIs, and to enumerate and connect to multiple machines from one app. For connecting directly to a single known machine, use Connect to a machine instead.

When to connect to the cloud

Use the cloud connection when your app needs any of these:

If your app only talks to one machine whose address you already know, skip this page and use Connect to a machine directly.

Prerequisites

Open a cloud connection

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

const client = await VIAM.createViamClient({
  credentials: {
    type: "api-key",
    authEntity: "<API-KEY-ID>",
    payload: "<API-KEY>",
  },
});

createViamClient returns a ViamClient with five platform-client properties:

Property Purpose
client.appClient Organizations, locations, machines, API keys, fragments, RBAC
client.dataClient Query and upload captured data
client.mlTrainingClient Launch and monitor ML training jobs
client.billingClient Read billing information
client.provisioningClient Device provisioning for custom provisioning apps

The default serviceHost is https://app.viam.com. Override it only if you are pointing at a self-hosted Viam platform.

import 'package:viam_sdk/viam_sdk.dart';

final viam = await Viam.withApiKey(
  'your-api-key-id',
  'your-api-key-secret',
);

Viam.withApiKey returns a Viam instance with five platform-client properties:

Property Purpose
viam.appClient Organizations, locations, machines, API keys, fragments, RBAC
viam.dataClient Query and upload captured data
viam.mlTrainingClient Launch and monitor ML training jobs
viam.billingClient Read billing information
viam.provisioningClient Device provisioning for custom provisioning apps

The default serviceHost is app.viam.com. Override it through the optional serviceHost parameter if you are pointing at a self-hosted Viam platform.

from viam.app.viam_client import ViamClient
from viam.rpc.dial import DialOptions

async def connect():
    dial_options = DialOptions.with_api_key(
        api_key='your-api-key-secret',
        api_key_id='your-api-key-id'
    )
    return await ViamClient.create_from_dial_options(dial_options)

client = await connect()

ViamClient exposes the same platform clients:

Property Purpose
client.app_client Organizations, locations, machines, API keys, fragments, RBAC
client.data_client Query and upload captured data
client.ml_training_client Launch and monitor ML training jobs
client.billing_client Read billing information
client.provisioning_client Device provisioning for custom provisioning apps
import (
    "context"
    "go.viam.com/rdk/app"
    "go.viam.com/rdk/logging"
)

logger := logging.NewDebugLogger("client")
client, err := app.CreateViamClientWithAPIKey(
    context.Background(),
    app.Options{},
    "your-api-key-secret",
    "your-api-key-id",
    logger,
)
if err != nil {
    logger.Fatal(err)
}

Access platform clients through methods on ViamClient:

Method Purpose
client.AppClient() Organizations, locations, machines, API keys, fragments, RBAC
client.DataClient() Query and upload captured data
client.MLTrainingClient() Launch and monitor ML training jobs
client.BillingClient() Read billing information
client.ProvisioningClient() Device provisioning

Unlike RobotClient, the cloud client does not hold a persistent WebRTC connection. Each method call is a separate request to the Viam cloud. There is no close() or disconnect() method to call when you are done.

Enumerate machines

Common pattern: list the organizations a user can access, then list machines in a selected organization.

const orgs = await client.appClient.listOrganizations();
console.log(`Found ${orgs.length} organizations`);

const orgId = orgs[0].id;
const summaries = await client.appClient.listMachineSummaries(orgId);
for (const location of summaries) {
  console.log(`Location: ${location.locationName}`);
  for (const machine of location.machines) {
    console.log(`  ${machine.machineName} (${machine.machineId})`);
  }
}

listMachineSummaries returns a list of location summaries, each containing the machines in that location. Pass fragmentIds to filter to machines that include specific fragments, or locationIds to scope to particular locations.

final orgs = await viam.appClient.listOrganizations();
print('Found ${orgs.length} organizations');

final orgId = orgs.first.id;
final locations = await viam.appClient.listLocations(orgId);

for (final location in locations) {
  print('Location: ${location.name}');
  final robots = await viam.appClient.listRobots(location.id);
  for (final robot in robots) {
    print('  ${robot.name} (${robot.id})');
  }
}
}

See the fleet API reference for the full method list on AppClient.

Connect to a machine from the cloud client

Once you have identified a machine, open a RobotClient connection to it.

const machine = await client.connectToMachine({
  id: "abc-123-def-456",
});

connectToMachine accepts either { host: "..." } with the machine’s FQDN or { id: "..." } with the machine’s UUID. It returns a RobotClient that behaves the same as one created by createRobotClient.

Note that connectToMachine uses reconnectMaxAttempts: 1 instead of the default of 10. If you need the standard reconnection behavior, call createRobotClient directly with the host and credentials you obtained from the cloud client.

final locations = await viam.appClient.listLocations(orgId);
final location = locations.first;
final robots = await viam.appClient.listRobots(location.id);
final robot = robots.first;

final robotClient = await viam.getRobotClient(robot);

getRobotClient takes a Robot object (returned from appClient.listRobots or appClient.getRobot) and returns a RobotClient connected to the machine’s main part.

Close the RobotClient when your app is done with the machine. See Connect to a machine for the close pattern and for error handling.

Handle errors

API key errors, network failures, and missing permissions all raise errors from createViamClient or Viam.withApiKey. Wrap the call in a try-catch the same way you would for a machine connection. The cloud client does not distinguish credential errors from network errors in its error messages; log the error verbatim when debugging.

If a subsequent appClient or dataClient call fails because the API key does not have permission for the target resource, the SDK throws an error from that specific call, not from the initial createViamClient. Check errors on every cloud method call that accesses resources across organizations or locations.

Next