Viam CLI

The Viam CLI (command line interface) tool enables you to manage your machines and modular resources across organizations and locations from the command line. The CLI lets you:

For example, this CLI command moves a servo to the 75 degree position:

viam machines part run --machine 82c608a-1be9-46a5 --organization "Artoo's Org" \
--location myLoc --part "mymachine-main" --data '{"name": "myServo", "angle_deg":75}' \
viam.component.servo.v1.ServoService.MoveRequest

Install

You can download the Viam CLI using one of the options below. Select the tab for your platform and architecture. If you are on Linux, you can use the uname -m command to determine your system architecture.

To download the Viam CLI on a macOS computer, run the following commands:

brew tap viamrobotics/brews
brew install viam

To download the Viam CLI on a Linux computer with the aarch64 architecture, run the following commands:

sudo curl -o /usr/local/bin/viam https://storage.googleapis.com/packages.viam.com/apps/viam-cli/viam-cli-stable-linux-arm64
sudo chmod a+rx /usr/local/bin/viam

To download the Viam CLI on a Linux computer with the amd64 (Intel x86_64) architecture, run the following commands:

sudo curl -o /usr/local/bin/viam https://storage.googleapis.com/packages.viam.com/apps/viam-cli/viam-cli-stable-linux-amd64
sudo chmod a+rx /usr/local/bin/viam

You can also install the Viam CLI using brew on Linux amd64 (Intel x86_64):

brew tap viamrobotics/brews
brew install viam

If you have Go installed, you can build the Viam CLI directly from source using the go install command:

go install go.viam.com/rdk/cli/viam@latest

To confirm viam is installed and ready to use, issue the viam command from your terminal. If you see help instructions, everything is correctly installed. If you do not see help instructions, add your local go/bin/* directory to your PATH variable. If you use bash as your shell, you can use the following command:

echo 'export PATH="$HOME/go/bin:$PATH"' >> ~/.bashrc

To later update the Viam CLI tool on Linux, use the steps above to reinstall the latest version. to later update the Viam CLI tool on macOS, run brew upgrade viam.

Authenticate

Once you have installed the Viam CLI, you must authenticate your CLI session with Viam in order to run CLI commands.

You can authenticate your CLI session using either a personal access token, or an organization, location, or machine part API key.

  • To authenticate your CLI session using a personal access token:

    viam login
    

    This will open a new browser window with a prompt to start the authentication process. If a browser window does not open, the CLI will present a URL for you to manually open in your browser. Follow the instructions to complete the authentication process.

  • To authenticate your CLI session using an organization, location, or machine part API key:

    viam login api-key --key-id <api-key-id> --key <organization-api-key-secret>
    

An authenticated session is valid for 24 hours, unless you explicitly log out.

After the session expires or you log out, you must re-authenticate to use the CLI again.

Create an organization API key

To use an API key to authenticate your CLI session, you must create one. You can do this from the organization’s settings page in the Viam app or with the CLI.

  1. First, authenticate your CLI session.

  2. Then, run the following command to create a new organization API key:

    viam organizations api-key create --org-id <org-id> --name <key-name>
    

    Where:

    • org-id is your organization ID. You can find your organization ID by running viam organizations list or by visiting your organization’s Settings page in the Viam app.
    • key-name is an optional name for your API key.

The command will return a key id and a key value. You will need both to authenticate.

Once created, you can use the organization API key to authenticate future CLI sessions or to use the SDKs. To switch to using an organization API key for authentication right away, logout then log back in using viam login api-key.

An organization can have multiple API keys.

Create a location API key

To use an location API key to authenticate your CLI session, you must first create one: You can do this from the organization’s settings page in the Viam app or with the CLI.

  1. First, authenticate your CLI session. If you don’t already have a location API key created, authenticate using a personal access token, an organization API key, or a machine part API key.

  2. Then, run the following command to create a new location API key:

    viam locations api-key create --location-id <location-id> --org-id <org-id> --name <key-name>
    

    Where:

    • location-id is your location ID. You can find your location ID by running viam locations list or by visiting your fleet’s page in the Viam app.
    • org-id is an optional organization ID to attach the key to. You can find your organization ID by running viam organizations list or by visiting your organization’s Settings page in the Viam app. If only one organization owns the location, you can omit the parameter. If multiple organizations own the location, you must specify the org-id explicitly.
    • key-name is an optional name for your API key. If omitted, a name will be auto-generated based on your login info and the current time.

The command will return a key id and a key value. You will need both to authenticate.

Once created, you can use the location API key to authenticate future CLI sessions or to connect to machines with the SDK. To switch to using a location API key for authentication right away, logout then log back in using viam login api-key.

A location can have multiple API keys.

Create a machine part API key

To use a machine part API key to authenticate your CLI session, you must first create one: You can do this from the organization’s settings page in the Viam app or with the CLI.

  1. First, authenticate your CLI session. If you don’t already have a machine part API key created, authenticate using a personal access token, an organization API key, or a location API key.

  2. Then, run the following command to create a new machine part API key:

    viam machines api-key create --machine-id <machine-id> --org-id <org-id> --name <key-name>
    

    Where:

    • machine-id is your machine’s ID. You can find your machine ID by running viam machines list, or by clicking the button in the upper-right corner of your machine’s page in the Viam app, and selecting Copy machine ID.
    • org-id is an optional organization ID to attach the key to. You can find your organization ID by running viam organizations list or by visiting your organization’s Settings page in the Viam app. If only one organization owns the robot, you can omit the parameter. If multiple organizations own the robot, you must specify the org-id explicitly.
    • key-name is an optional name for your API key. If omitted, a name will be auto-generated based on your login info and the current time.

The command will return a key id and a key value. You will need both to authenticate.

Once created, you can use the machine part API key to authenticate future CLI sessions or to connect to your machine with the SDK. To switch to using a machine part API key for authentication right away, logout then log back in using viam login api-key.

A location can have multiple API keys.

Manage your machines with the Viam CLI

With the Viam CLI installed and authenticated, you can use it to issue commands to your machine fleet or manage custom modules. All Viam CLI commands use the following format:

viam [global options] command [command options] [arguments...]
ParameterDescription
Global optionsoptional - list of flags that apply for commands.
Commandrequired - the specific CLI command to run.
Command optionsrequired for some commands - the operation to run for the specified command.
Argumentsrequired for some commands - the arguments for the specified command operation. Some commands take positional arguments, some named arguments.

See the list of commands below.

CLI help

The Viam CLI has a built-in help system that lists all available commands. You can access it at any time by issuing the command:

viam --help

You can also access contextual help by passing the --help flag as a command option for any CLI command, for example:

viam organizations --help

Commands

dataset

The dataset command allows you to manage machine data in datasets. With it, you can add or remove images from a dataset, export data from a dataset, or filter a dataset by tags.

viam dataset create --org-id=<org-id> --name=<name>
viam dataset rename --dataset-id=<dataset-id> --name=<name>
viam dataset list --org-id=<org-id>
viam dataset list --dataset-ids=<dataset-ids>
viam dataset delete --dataset-id=<dataset-id>
viam dataset export --destination=<output-directory> --dataset-id=<dataset-id>
viam dataset data add filter --dataset-id=<dataset-id> [...named args]
viam dataset data remove filter --dataset-id=<dataset-id> [...named args]
viam dataset data add ids --dataset-id=<dataset-id> --org-id=<org-id> --location-id=<location-id> --file-ids=<file-ids>
viam dataset data remove ids --dataset-id=<dataset-id> --org-id=<org-id> --location-id=<location-id> --file-ids=<file-ids>

Examples:

# create a new dataset
viam dataset create --org-id=123 --name=MyDataset

# rename dataset 123 from MyDataset to MyCoolDataset
viam dataset rename --dataset-id=123 --name=MyCoolDataset

# list dataset information from the specified org
viam dataset list --org-id=123

# list dataset information from the specified dataset ids
viam dataset list --dataset-ids=123,456

# delete the specified dataset
viam dataset delete --dataset-id=123

# export dataset abc to output directory ./dataset/example in two folders called "data" and "metadata"
viam dataset export --destination=./dataset/example --dataset-id=abc

# add images tagged with the "example" tag between January and October of 2023 to dataset abc
viam dataset data add filter --dataset-id=abc --location-id=123 --org-id=456 --start=2023-01-01T05:00:00.000Z --end=2023-10-01T04:00:00.000Z --tags=example

# remove images tagged with the "example" tag between January and October of 2023 to dataset abc
viam dataset data remove filter --dataset-id=abc --location-id=123 --org-id=456 --start=2023-01-01T05:00:00.000Z --end=2023-10-01T04:00:00.000Z --tags=example

# add images with file IDs aaa and bbb in the org 123 and location 456 to dataset abc
viam dataset data add ids --dataset-id=abc --org-id=123 --location-id=456 --file-ids=aaa,bbb

# remove images with file IDs aaa and bbb in the org 123 and location 456 from dataset abc
viam dataset data remove ids --dataset-id= abc --org-id=123 --location-id=456 --file-ids=aaa,bbb

Command options

Command optionDescriptionPositional arguments
createCreate a new dataset-
renameRename an existing dataset-
listList dataset information from specified IDs or for an org ID-
deleteDelete a dataset-
data addAdd a new image to an existing dataset by its file id, add a group of images by specifying a filterids, filter
data removeRemove a new image to an existing dataset by its file id, or remove a group of images by specifying a filterids, filter
exportDownload all the data from a dataset-
--helpReturn help-
Positional arguments
ArgumentDescription
filteradd or remove images from a dataset using a filter. See Using the filter argument).
idsadd or remove images from a dataset by specifying one or more file ids as a comma-separated list. See Using the ids argument).
--helpReturn help
Named arguments
ArgumentDescriptionApplicable commandsRequired?
--dataset-idDataset to perform an operation on. To retrieve the ID, navigate to your dataset’s page in the Viam app, click in the left-hand menu, and click Copy dataset IDrename, delete, data add, data remove, exportRequired
--dataset-idsDataset IDs of datasets to be listed. To retrieve these IDs, navigate to your dataset’s page in the Viam app, click in the left-hand menu, and click Copy dataset IDlistOptional
--destinationOutput directory for downloaded dataexportRequired
--endISO-8601 timestamp indicating the end of the intervaldata add, data removeOptional
--file-idsThe file-ids of the files to perform an operation ondata add, data remove, exportRequired
--include-jsonlSet to true to include JSON Lines files for local testingexportOptional
--location-idThe location ID for the location in which to perform an operation (only accepts one location id)data add, data removeRequired
--nameThe name of the dataset to create or renamecreate, renameRequired
--org-idOrganization ID of the organization the dataset belongs tocreate, data add, data remove, listRequired
--parallelNumber of download requests to make in parallel, with a default value of 100exportOptional
--startISO-8601 timestamp indicating the start of the intervaldata add, data removeOptional
--tagsFilter by specified tag (accepts comma-separated list)data add, data removeOptional
Using the ids argument

When you use the viam dataset data add and viam dataset data remove commands, you can specify the images to add or remove using their file ids as a comma-separated list. For example, the following command adds three images specified by their file ids to the specified dataset:

viam dataset data add ids --dataset-id=abc --location-id=123 --org-id=123 --file-ids=abc,123,def

The following command tags two images specified by their file ids in the specified organization and location with three tags:

viam data tag ids add --tags=new_tag_1,new_tag_2,new_tag_3 --org-id=123 --location-id=123 --file-ids=123,456

To find your organization’s ID, run viam organization list or navigate to your organization’s Settings page in the Viam app. Find Organization ID and click the copy icon.

To find the dataset ID of a given dataset, go to the DATASETS subtab of the DATA tab on the Viam app and select a dataset. Click in the left-hand menu and click Copy dataset ID.

To find a location ID, run viam locations list or visit your fleet’s page in the Viam app and copy from Location ID.

To find the file ID of a given image, navigate to the DATA tab in the Viam app and select your image. Its File ID is shown under the DETAILS subtab that appears on the right.

You cannot use filter arguments, such as --start or --end when using ids.

See Datasets for more information.

Using the filter argument

When you use the viam dataset data add, viam dataset data remove or viam data tag commands, you can optionally filter by common search criteria to add or remove a specific subset of images based on a search filter. For example, the following command adds all images captured between January 1 and October 1, 2023, that have the example tag applied, to the specified dataset:

viam dataset data add filter --dataset-id=abc --org-ids=123 --start=2023-01-01T05:00:00.000Z --end=2023-10-01T04:00:00.000Z --tags=example

The following command adds "new_tag_1" and "new_tag_2" to all images of type "image/jpeg" or "image/png" captured by the machine named "cool-machine" in organization 8484 and location 012:

viam data tag filter add --tags=new_tag_1,new_tag_2 --location-ids=012 --machine-name=cool-machine --org-ids=84842  --mime-types=image/jpeg,image/png

To find the dataset ID of a given dataset, go to the DATASETS subtab under the DATA tab on the Viam app and select a dataset. Click in the left-hand menu and click Copy dataset ID.

To find a location ID, run viam locations list or visit your fleet’s page in the Viam app and copy from Location ID.

You can also have the filter parameters generated for you using the Filters pane of the DATA tab. Navigate to the DATA tab in the Viam app, make your selections from the search parameters under the Filters pane (such as robot name, start and end time, or tags), and click the Copy export command button. A viam data export command string will be copied to your clipboard that includes the search parameters you selected. Removing the viam data export string, you can use the same filter parameters (such as --start, --end, etc) with your viam data database add filter, viam data database remove filter, or viam data tag filter commands, except you must exclude the --data-type and --destination flags, which are specific to viam data export.

You cannot use the --file-ids argument when using filter.

See Datasets for more information.

data

The data command allows you to manage machine data. With it, you can export data in a variety of formats, delete specified data, add or remove tags from all data that matches a given filter, or configure a database user to enable querying synced data directly in the cloud.

viam data export --destination=<output path> --data-type=<output data type> [...named args]
viam data delete --org-ids=<org-ids> --start=<timestamp> --end=<timestamp> [...named args]
viam data database configure --org-id=<org-id> --password=<db-user-password>
viam data database hostname --org-id=<org-id>
viam data tag ids add --tags=<tags> --org-id=<org_id> --location-id=<location_id> --file-ids=<file_ids>
viam data tag ids remove --tags=<tags> --org-id=<org_id> --location-id=<location_id> --file-ids=<file_ids>
viam data tag filter add --tags=<tags> [...named args from filter]
viam data tag filter remove --tags=<tags> [...named args from filter]

Examples:

# export tabular data to /home/robot/data for org abc, location 123
viam data export --destination=/home/robot/data --data-type=tabular \
--org-ids=abc --location-ids=123

# export binary data from all orgs and locations, component name myComponent
viam data export --destination=/home/robot/data --data-type=binary \
--component-name myComponent

# delete binary data of mime type image/jpeg in an organization between a specified timestamp
viam data delete binary --org-ids=123 --mime-types=image/jpeg --start 2024-08-20T14:10:34-04:00 --end 2024-08-20T14:16:34-04:00

# configure a database user for the Viam organization's MongoDB Atlas Data
# Federation instance, in order to query tabular data
viam data database configure --org-id=abc --password=my_password123

# get the hostname to access a MongoDB Atlas Data Federation instance
viam data database hostname --org-id=abc

# add tags to all data that matches the given ids
viam data tag ids add --tags=new_tag_1,new_tag_2,new_tag_3 --org-id=123 --location-id=123 --file-ids=123,456

# remove tags from all data that matches the given ids
viam data tag ids remove --tags=new_tag_1,new_tag_2,new_tag_3 --org-id=123 --location-id=123 --file-ids=123,456

# add tags to all data that matches a given filter
viam data tag filter add --tags=new_tag_1,new_tag_2 --location-ids=012 --machine-name=cool-machine --org-ids=84842  --mime-types=image/jpeg,image/png

# remove tags from all data that matches a given filter
viam data tag filter remove --tags=new_tag_1 --location-ids=012 --machine-name=cool-machine --org-ids=84842  --mime-types=image/jpeg,image/png

Viam currently only supports deleting approximately 500 files at a time. To delete more data iterate over the data with a shell script:

# deleting one hour of image data
for i in {00..59}; do
  viam data delete binary --org-ids=<org-id> --mime-types=image/jpeg,image/png --start=2024-05-13T11:00:00.000Z --end=2024-05-13T11:${i}:00.000Z
done

Command options

Command optionDescriptionPositional arguments
exportExport data in a specified format to a specified location.-
tagAdd or remove tags from data matching the ids or filter.ids, filter
database configureCreate a new database user for the Viam organization’s MongoDB Atlas Data Federation instance, or change the password of an existing user. See Configure data query.-
database hostnameGet the MongoDB Atlas Data Federation instance hostname and connection URI. See Configure data query.-
delete binaryDelete binary data from the Viam Cloud.-
delete tabularDelete tabular data from the Viam Cloud.-
--helpReturn help-
Positional arguments: tag
ArgumentDescription
filteradd or remove images or tags from a dataset using a filter. See Using the filter argument.
idsadd or remove images or tags from a dataset by specifying one or more file ids as a comma-separated list. See Using the ids argument.
--helpReturn help
Named arguments
ArgumentDescriptionApplicable commandsRequired?
--destinationOutput directory for downloaded data.exportRequired
--data-typeData type to be downloaded: either binary or tabular.exportRequired
--component-nameFilter by specified component name.export, delete, tag filterOptional
--component-typeFilter by specified component type.export, delete, tag filterOptional
--component-modelFilter by specified component model.export, deleteOptional
--delete-older-than-daysNumber of days, 0 means all data will be deleted.deleteOptional
--timeoutNumber of seconds to wait for file downloads. Default: 30.exportOptional
--startISO-8601 timestamp indicating the start of the interval.export, delete, dataset, tag filterOptional
--endISO-8601 timestamp indicating the end of the interval.export, delete, dataset, tag filterOptional
--file-idsFile-ids to add or remove tags from.tag idsRequired
--location-idLocation ID for the file ids being added or removed from the specified dataset (only accepts one location id).dataset, tag idsRequired
--location-idsFilter by specified location ID (accepts comma-separated list). See Using the ids argument for instructions on retrieving these values.export, delete, tag filterOptional
--methodFilter by specified method.export, delete, tag filterOptional
--mime-typesFilter by specified MIME type (accepts comma-separated list).export, delete, tag filterfalse
--org-idOrg ID for the database user being configured (with database) or data being tagged. (tag ids)database configure, database hostname, tag idsRequired
--org-idsFilter by specified organizations ID (accepts comma-separated list). See Using the ids argument for instructions on retrieving these values.export, delete, tag filterOptional
--parallelNumber of download requests to make in parallel, with a default value of 10.export, delete, dataset exportOptional
--part-idFilter by specified part ID.export, delete, tag filterOptional
--part-nameFilter by specified part name.export, delete, tag filterOptional
--machine-idFilter by specified machine ID.export, delete, tag filterOptional
--machine-nameFilter by specified machine name.export, delete, tag filterOptional
--tagsFilter by (export, delete) or add (tag) specified tag (accepts comma-separated list).export, delete, tag ids, tag filterOptional
--bbox-labelsString labels corresponding to bounding boxes within images.tag filterOptional
--chunk-limitMaximum number of results per download request (tabular data only).tag filterOptional
--passwordPassword for the database user being configured.database configureRequired

locations

The locations command allows you to manage the locations that you have access to. With it, you can list available locations, filter locations by organization, or create a new location API key.

viam locations list [<organization id>]
viam locations api-key create --location-id=<location-id>

Command options

Command optionDescriptionPositional arguments
listList all locations (name and id) that the authenticated session has access to, grouped by organizationorganization id : (optional) return results for specified organization only
api-keyWork with an api-key for your locationcreate
--helpReturn help-
Positional arguments: api-key
ArgumentDescription
createCreate an API key for a specific location
--helpReturn help
Named arguments
ArgumentDescriptionApplicable commandsRequired?
--location-idThe location to create an API key forapi-keyRequired
--nameThe name of the API keyapi-keyOptional
--org-idThe organization ID to attach the key toapi-keyOptional

login

The login command allows you to authorize your device for CLI usage.

viam login
viam login api-key --key-id=<api-key-uuid> --key=<api-key-secret-value>
viam login print-access-token

Use viam login to authenticate using a personal access token, or viam login api-key to authenticate using an API key. See Authenticate.

Command options

Command optionDescriptionPositional arguments
api-keyAuthenticate to Viam using an organization, location, or machine part API key.-
print-access-tokenPrints the access token used to authenticate the current CLI session.-
--disable-browser-openAuthenticate in a headless environment by preventing the opening of the default browser during login (default: false).-
--helpReturn help.-
Named arguments
ArgumentDescriptionApplicable commandsRequired?
--key-idThe key id (UUID) of the API key.api-keyRequired
--keyThe key value of the API key.api-keyRequired

logout

The logout command ends an authenticated CLI session.

viam logout

module

The module command allows to you to work with modules. This includes:

  • Generating stub files for a new module
  • Creating metadata for a modular resource
  • Uploading a new module to the Viam registry
  • Uploading a new version of your module to the Viam registry
  • Updating an existing module in the Viam Registry
  • Updating a module’s metadata file based on models it provides
  • Building your module for different architectures using cloud runners
  • Building a module locally and running it on a target device. Rebuilding & restarting if already running.

See Upload a custom module and Update an existing module for more information.

If you update and release your module as part of a continuous integration (CI) workflow, you can also automatically upload new versions of your module on release using a GitHub Action.

viam module generate
viam module create --name=<module-name> [--org-id=<org-id> | --public-namespace=<namespace>]
viam module update [--module=<path to meta.json>]
viam module update-models --binary=<binary> [...named args]
viam module build start --version=<version> [...named args]
viam module build local --module=<path to meta.json> [arguments...]
viam module build list [command options] [arguments...]
viam module build logs --id=<id> [...named args]
viam module reload [...named args]
viam module upload --version=<version> --platform=<platform> [--org-id=<org-id> | --public-namespace=<namespace>] [--module=<path to meta.json>] <module-path>

Examples:

# generate stub files for a new modular resource by following prompts
viam module generate

# generate metadata for a module named 'my-module' using your organization's public namespace:
viam module create --name=my-module --public-namespace=my-namespace

# generate metadata for a module named "my-module" using your organization's organization ID:
viam module create --name=my-module --org-id=abc

# update an existing module
viam module update --module=./meta.json

# updating a module's metadata file based on models it provides
viam module update-models --binary=./packaged-module.tar.gz --module=./meta.json

# initiate a cloud build
viam module build start --version "0.1.2"

# initiate a build locally without running a cloud build job
viam module build local

# list all in-progress builds and their build status
viam module build list

# initiate a build and return the build logs as soon as completed
viam module build logs --wait --id=$(viam module build start --version "0.1.2")

# restart a module running on your local viam-server, by name, without building or reconfiguring
viam module reload --restart-only --id viam:python-example-module

# upload a new or updated custom module to the Viam Registry:
viam module upload --version=1.0.0 --platform=darwin/arm64 packaged-module.tar.gz

Command options

Command optionDescriptionPositional arguments
generateAuto-generate stub files for a new module by following prompts.-
createGenerate new metadata for a custom module on your local filesystem.-
updateUpdate an existing custom module on your local filesystem with recent changes to the meta.json file. Note that the upload command automatically runs update for you; you do not need to explicitly run update if you are also running upload.-
update-modelsUpdate the module’s metadata file with the models it provides.-
uploadValidate and upload a new or existing custom module on your local filesystem to the Viam Registry. See Upload validation for more information.module-path : specify the path to the file, directory, or compressed archive (with .tar.gz or .tgz extension) that contains your custom module code.
reloadBuild a module locally and run it on a target device. Rebuild and restart if it is already running.-
build startStart a module build in a cloud runner using the build step in your meta.json file. See Using the build subcommand.-
build localStart a module build locally using the build step in your meta.json file. See Using the build subcommand.-
build listList the status of your cloud module builds. See Using the build subcommand.-
build logsShow the logs from a specific cloud module build. See Using the build subcommand.-
--helpReturn help.-
Named arguments
ArgumentDescriptionApplicable commandsRequired?
--binaryThe binary for the module to run. The binary has to work on the OS or processor of the device.update-modelsRequired
--countNumber of cloud builds to list, defaults to displaying all buildsbuild listOptional
--forceSkip local validation of the packaged module, which may result in an unusable module if the contents of the packaged module are not correctuploadOptional
--idThe build ID to list or show logs for, as returned from build startbuild list, build logsOptional
--moduleThe path to the meta.json file for the custom module, if not in the current directoryupdate, upload, buildOptional
--resource-subtypeThe API to implement with the modular resource. For example, motor. We recommend not using this option and instead following the prompts after running the command.generateOptional
--resource-typeWhether the new resource is a component or a service. For example, component. We recommend not using this option and instead following the prompts.generateOptional
--local-onlyCreate a meta.json file for local use, but don’t create the module on the backend (default: false).createOptional
--nameThe name of the custom module to be createdcreateRequired
--org-idThe organization ID to associate the module to. See Using the --org-id argumentcreate, uploadRequired
--public-namespaceThe namespace to associate the module to. See Using the --public-namespace argumentcreate, uploadRequired
--platformThe architecture of your module binary. See Using the --platform argumentupload, build logsRequired
--versionThe version of your module to set for this upload. See Using the --version argumentuploadRequired
--waitWait for the build to finish before outputting any logsbuild logsOptional
Using the --org-id and --public-namespace arguments

All of the module commands accept either the --org-id or --public-namespace argument.

  • Use the --public-namespace argument to supply the namespace of your organization. This will upload your module to the Viam Registry and share it with other users.
  • Use the --org-id to provide your organization ID instead, This will upload your module privately within your organization.

You may use either argument for the viam module create command, but must use --public-namespace for the update and upload commands when uploading as a public module ("visibility": "public") to the Viam Registry.

Using the --platform argument

The --platform argument accepts one of the following architectures:

ArchitectureDescriptionCommon use case
anyAny supported OS running any supported architecture.Suitable for most Python modules that do not require OS-level support (such as platform-specific dependencies).
any/amd64Any supported OS running the amd64 architecture.Suitable for most Docker-based modules on amd64.
any/arm64Any supported OS running the arm64 (aarch64) architecture.Suitable for most Docker-based modules on arm64.
linux/anyLinux machines running any architecture.Suitable for Python modules that also require Linux OS-level support (such as platform-specific dependencies).
darwin/anymacOS machines running any architecture.Suitable for Python modules that also require macOS OS-level support (such as platform-specific dependencies).
linux/amd64Linux machines running the Intel x86_64 architecture.Suitable for most C++ or Go modules on Linux amd64.
linux/arm64Linux machines running the arm64 (aarch64) architecture, such as the Raspberry Pi.Suitable for most C++ or Go modules on Linux arm64.
linux/arm32v7Linux machines running the arm32v7 architecture.Suitable for most C++ or Go modules on Linux arm32v7.
linux/arm32v6Linux machines running the arm32v6 architecture.Suitable for most C++ or Go modules on arm32v6.
darwin/amd64macOS machines running the Intel x86_64 architecture.Suitable for most C++ or Go modules on macOS amd64.
darwin/arm64macOS machines running the arm64 architecture, such as Apple Silicon.Suitable for most C++ or Go modules on macOS arm64.

You can use the uname -m command on your computer or board to determine its system architecture.

The viam module upload command only supports one platform argument at a time. If you would like to upload your module with support for multiple platforms, you must run a separate viam module upload command for each platform. Use the same version number when running multiple upload commands of the same module code if only the platform support differs.

If you specify a platform that includes any (such as any, any/amd64, or linux/any), a machine that deploys your module will select the most restrictive architecture from the ones you have provided for your module. For example, if you upload your module with support for any/amd64 and then also upload with support for linux/amd64, a machine running the linux/amd64 architecture deploys the linux/amd64 version, while a machine running the darwin/amd64 architecture deploys the any/amd64 version.

The Viam Registry page for your module displays the platforms your module supports for each version you have uploaded.

If you are using the build logs command, the --platform argument instead restricts the logs returned by the command to only those build jobs that match the specified platform.

Using the --version argument

The --version argument accepts a valid semver 2.0 version (example: 1.0.0). You set an initial version for your custom module with your first viam module upload command for that module, and can later increment the version with subsequent viam module upload commands.

Once your module is uploaded, users can select which version of your module to use on their machine from your module’s page on the Viam Registry. Users can choose to pin to a specific patch version, permit upgrades within major release families or only within minor releases, or permit continuous updates.

When you update a module configuration and then upload it, the entrypoint for that module defined in the meta.json file is associated with the specific --version for that upload. Therefore, you are able to change the entrypoint file from version to version, if desired.

Upload validation

When you upload a module, the command performs basic validation of your module to check for common errors. The following criteria are checked for every upload:

  • The module must exist on the filesystem at the path provided to the upload command.
  • The entry point file specified in the meta.json file must exist on the filesystem at the path specified.
  • The entry point file must be executable.
  • If the module is provided to the upload command as a compressed archive, the archive must have the .tar.gz or .tgz extension.
The meta.json file

When uploading a custom module, the Viam Registry tracks your module’s metadata in a meta.json file. This file is created for you when you run the viam module generate or viam module create command, with the module_id field pre-populated based on the --name you provided to create. If you later make changes to this file, you can register those changes with the Viam registry by using the viam module update command.

The meta.json file includes the following configuration options:

NameTypeInclusionDescription
module_idstringRequiredThe name of the module, including its namespace.
visibilitystringRequiredWhether the module is accessible only to members of your organization (private), or visible to all Viam users (public). You can change this setting later using the viam module update command.

Default: private
urlstringOptionalThe URL of the GitHub repository containing the source code of the module.
descriptionstringRequiredA description of your module and what it provides.
modelsobjectRequiredA list of one or more models provided by your custom module. You must provide at least one model, which consists of an api and model key-value pair.
entrypointstringRequiredThe name of the file that starts your module program. This can be a compiled executable, a script, or an invocation of another program. If you are providing your module as a single file to the upload command, provide the path to that single file. If you are providing a directory containing your module to the upload command, provide the path to the entry point file contained within that directory. You can change the entrypoint file from version to version, if desired.

For example, the following represents the configuration of an example my-module module in the acme namespace:

{
  "module_id": "acme:my-module",
  "visibility": "public",
  "url": "https://github.com/<my-repo-name>/my-module",
  "description": "An example custom module.",
  "models": [
    {
      "api": "rdk:component:generic",
      "model": "acme:demo:my-model"
    }
  ],
  "entrypoint": "<PATH-TO-EXECUTABLE>"
}

See Upload a custom module and Update an existing module for a detailed walkthrough of the viam module commands.

See Modular resources for a conceptual overview of modules and the modular resource system at Viam.

Using the build subcommand

You can use the module build start or module build local commands to build your custom module according to the build steps in your meta.json file:

  • Use build start to build or compile your module on a cloud build host that might offer more platform support than you have access to locally.
  • Use build local to quickly test that your module builds or compiles as expected on your local hardware.

To configure your module’s build steps, add a build object to your meta.json file like the following:

"build": {
  "setup": "./setup.sh",                  // optional - command to install your build dependencies
  "build": "./build.sh",                  // command that will build your module
  "path" : "dist/archive.tar.gz",         // optional - path to your built module
                                          // (passed to the 'viam module upload' command)
  "arch" : ["linux/amd64", "linux/arm64"] // architecture(s) to build for
}
Click to view example setup.sh
#!/bin/bash
set -e
UNAME=$(uname -s)

if [ "$UNAME" = "Linux" ]
then
    echo "Installing venv on Linux"
    sudo apt-get install -y python3-venv
fi
if [ "$UNAME" = "Darwin" ]
then
    echo "Installing venv on Darwin"
    brew install python3-venv
fi

python3 -m venv .venv
. .venv/bin/activate
pip3 install -r requirements.txt
Click to view example build.sh (with setup.sh)
#!/bin/bash
pip3 install -r requirements.txt
python3 -m PyInstaller --onefile --hidden-import="googleapiclient" src/main.py
tar -czvf dist/archive.tar.gz <PATH-TO-EXECUTABLE>
Click to view example build.sh (without setup.sh)
#!/bin/bash
set -e
UNAME=$(uname -s)

if [ "$UNAME" = "Linux" ]
then
    echo "Installing venv on Linux"
    sudo apt-get install -y python3-venv
fi
if [ "$UNAME" = "Darwin" ]
then
    echo "Installing venv on Darwin"
    brew install python3-venv
fi

python3 -m venv .venv
. .venv/bin/activate
pip3 install -r requirements.txt
python3 -m PyInstaller --onefile --hidden-import="googleapiclient" src/main.py
tar -czvf dist/archive.tar.gz <PATH-TO-EXECUTABLE>

For example, the following extends the my-module meta.json file from the previous section using the single build file approach, adding a new build object to control its build parameters when used with module build start or module build local:

{
  "module_id": "acme:my-module",
  "visibility": "public",
  "url": "https://github.com/<my-repo-name>/my-module",
  "description": "An example custom module.",
  "models": [
    {
      "api": "rdk:component:generic",
      "model": "acme:demo:my-model"
    }
  ],
  "build": {
    "setup": "./setup.sh",
    "build": "./build.sh",
    "path": "dist/archive.tar.gz",
    "arch": ["linux/amd64", "linux/arm64"]
  },
  "entrypoint": "<PATH-TO-EXECUTABLE>"
}

When you initiate a build job using either start or local, the command returns the build ID of your job. Provide that build ID to the module build logs command to show the relevant build logs for that build.

For example, use the following to initiate a build, and return the build logs as soon as it completes:

viam module build logs --wait --id=$(viam module build start --version "0.1.2")

To list all in-progress builds and their build status, use the following command:

viam module build list

organizations

The organizations command allows you to list the organizations your authenticated session has access to, and to create a new organization API key.

viam organizations list
viam organizations api-key create --org-id=<org-id> [--name=<key-name>]

Examples:

# list all the organizations that you are currently authenticated to
viam organizations list

# create a new organization api key in org 123
viam organizations api-key create --org-id=123 --name=my-key

See create an organization API key for more information.

Command options

Command optionDescriptionPositional arguments
listList all organizations (name, id, and namespace) that the authenticated session has access to.-
api-keyCreate a new organization API keycreate
--helpReturn help-
Positional arguments: api-key
ArgumentDescription
createCreate an API key for an organization
--helpReturn help
Named arguments
ArgumentDescriptionApplicable commandsRequired?
--org-idThe organization to create an API key forapi-keyRequired
--nameThe optional name for the organization API key. If omitted, a name will be auto-generated based on your login info and the current timeapi-keyOptional

packages

The packages command allows you to upload packages to the Viam Cloud or export packages from the Viam Cloud.

viam packages upload --org-id=<org-id> --name=<package-name> --version=<version> --type=<type> --path=<path-to-package.tar.gz>
viam packages export --org-id=<org-id> --name=<package-name> --version=<version> --type=<type> --destination=<path-to-export-destination>

Examples:

viam packages upload --org-id=123 --name=MyMLModel --version=1.0.0 --type=ml_model --path=./the_package.tar.gz
viam packages export --org-id=123 --name=MyMLModel --version=latest --type=ml_model --destination=.

Command options

Command optionDescriptionPositional arguments
uploadUpload a package to the Viam Cloud-
exportDownload a package from the Viam Cloud-
Named arguments
ArgumentDescriptionApplicable commandsRequired?
--org-idThe organization ID of the packageupload, exportRequired
--nameThe name of the packageupload, exportRequired
--versionThe version of the package or latestupload, exportRequired
--typeThe type of the package: ml_model, archive, module, slam_map, or unspecified.upload, exportRequired
--pathThe path to the package for upload. The package should be zipped with tar and have the .tar.gz extension.uploadRequired
--destinationThe output directory for downloaded package.exportRequired

machines (alias robots)

The machines command allows you to manage your machine fleet. This includes:

  • Listing all machines that you have access to, filtered by organization and location.
  • Creating API keys to grant access to a specific machine
  • Retrieving machine and machine part status
  • Retrieving machine and machine part logs
  • Controlling a machine by issuing component and service commands
  • Accessing your machine with a secure shell (when this feature is enabled)
viam machines list
viam machines status --organization=<org name> --location=<location name> --machine=<machine id>
viam machines logs --organization=<org name> --location=<location name> --machine=<machine id> [...named args]
viam machines api-key create --machine-id=<machine-id> [...named args]
viam machines part logs --machine=<machine> --part=<part> [...named args]
viam machines part status --organization=<org name> --location=<location name> --machine=<machine id>
viam machines part run --organization=<org name> --location=<location name> --machine=<machine id> [--stream] --data <meth>
viam machines part shell --organization=<org name> --location=<location name> --machine=<machine id>
viam machines part restart --machine=<machine id> --part=<part id>

Examples:

# list all machines you have access to
viam machines list

# get machine status
viam machines status  --machine=123 --organization="Robot's Org" --location=myLoc

# create an api key for a machine
viam machines api-key create --machine-id=123 --name=MyKey

# stream logs from a machine
viam machines logs --machine=123 \
--organization="Robot's Org" --location=myLoc

# stream logs from a machine part
viam machines part logs --machine=123 \
--organization="Robot's Org" --location=myLoc --part=myrover-main --tail=true

# stream classifications from a machine part every 500 milliseconds from the Viam Vision Service with classifier "stuff_detector"
viam machines part run --machine=123 \
--organization="Robot's Org" --location=myLoc --part=myrover-main --stream=500ms \
--data='{"name": "vision", "camera_name": "cam", "classifier_name": "stuff_classifier", "n":1}' \
viam.service.vision.v1.VisionService.GetClassificationsFromCamera

# restart a part of a specified machine
viam machines part restart --machine=123 --part=456

Command options

Command optionDescriptionPositional arguments
listList all machines that the authenticated session has access to, filtered by organization and location.-
api-keyWork with an api-key for your machinecreate (see positional arguments: api-key)
statusRetrieve machine status for a specified machine-
logsRetrieve logs for a specified machine-
partManage a specified machine partstatus, run, logs, shell, restart (see positional arguments: part)
--helpReturn help-
Positional arguments: api-key
ArgumentDescription
createCreate an API key for a specific machine
--helpReturn help
Positional arguments: part
ArgumentDescription
statusRetrieve machine status for a specified machine part
runRun a component or service command, optionally at a specified interval. For commands that return data in their response, you can use this to stream data.
logsGet logs for the specified machine part
shellAccess a machine part securely using a secure shell. To use this feature you must add the ViamShellDanger fragment to your machine.
restartRestart a machine part.
--helpReturn help
Named arguments
ArgumentDescriptionApplicable commandsRequired?
--organizationOrganization name or ID that the machine belongs tolist, status, logs, partRequired
--locationLocation name or ID that the machine belongs to or to list machines inlist, status, logs, partRequired
--machineMachine name or ID for which the command is being issuedstatus, logs, part, part restartRequired
--errorsBoolean, return only errors (default: false)logsOptional
--partPart name or ID for which the command is being issuedlogs, partOptional
--tailTail (stream) logs, boolean(default false)part logsOptional
--streamIf specified, the interval in which to stream the specified data, for example, 100ms or 1spart runOptional
--dataCommand data for the command being request to run (see data argument)part runRequired
--machine-idThe machine to create an API key forapi-keyRequired
--nameThe optional name of the API keyapi-keyOptional
--org-idThe optional organization ID to attach the key toapi-keyOptional
Using the --stream and --data arguments

Issuing the part command with the run positional argument allows you to run component and service (resource) commands for a selected machine part.

The --data parameter is required and you must specify both:

  • Method arguments in JSON format
  • A resource method (in the form of the protobuf package and method path)

The format of what is passed to the --data argument is:

'{"arg1": "val1"}' <protobuf path>

You can find the protobuf path for the Viam package and method in the Viam API package by navigating to the component or service directory and then clicking on the resource file. The protobuf path is the package name.

For example:

'{"name": "vision", "camera_name": "cam", "classifier_name": "my_classifier", "n":1}' \
viam.service.vision.v1.VisionService.GetClassificationsFromCamera

The --stream argument, when included in the CLI command prior to the --data command, will stream data back at the specified interval.

training-script

Manage training scripts for custom ML training.

viam training-script upload --framework=<framework> --org-id=<org-id> --path=<path-to-script> --script-name=<script-name> --type=<type>
viam training-script update --org-id=<org-id> --script-name=<script-name> --visibility=<visibility>

Examples:

# upload a single label classification script in the tflite framework to organization 123
viam training-script upload --framework=tflite --org-id=123 --path=. --script-name=MyCustomTrainingScript --type=single_label_classification

# update MyCustomTrainingScript with public visibility
viam training-script update --org-id=123 --script-name=MyCustomTrainingScript --visibility=public --description="A single label classification training script"

Command options

Command optionDescriptionPositional arguments
uploadUpload ML training script to the registry-
updateUpdate visibility of ML training script in registry-
Named arguments
ArgumentDescriptionApplicable commandsRequired?
--pathThe path to ML training scripts for upload.uploadRequired
--org-idThe organization ID to host the scripts in. You can find your organization ID by running viam organizations list or by visiting your organization’s Settings page in the Viam app.upload, updateRequired
--script-nameName of the ML training script to update or upload.upload, updateRequired
--visibilityVisibility of the registry item, can be public, private, or draft.updateRequired
--versionVersion of the ML training script to upload.uploadOptional
--descriptionDescription of the ML training script.updateOptional
--frameworkFramework of the ML training script to upload, can be tflite, tensorflow, pytorch, or onnx.uploadOptional
--urlURL of GitHub repository associated with the training script.uploadOptional
--typeTask type of the ML training script to upload, can be single_label_classification, multi_label_classification, or object_detection.uploadOptional
--draftIndicate draft mode, drafts are not viewable in the registry.uploadOptional

train

Use a training script to train an ML model on data.

viam train submit managed --dataset-id=<dataset-id> --model-org-id=<model-org-id> --model-name=<model-name> --model-type=<model-type> --model-labels=<model-labels> [...named args]
viam train submit custom from-registry --dataset-id=<dataset-id> --org-id=<org-id> --model-name=<model-name> --script-name=<script-name> --version=<version> --args=<arg-key>=<arg-value> [...named args]
viam train submit custom with-upload --dataset-id=<dataset-id> --org-id=<org-id> --model-name=<model-name> --path=<path> --script-name=<script-name> --args=<arg-key>=<arg-value> [...named args]
viam train get --job-id=<job-id>
viam train logs --job-id=<job-id>
viam train cancel --job-id=<job-id>
viam train list --org-id=<org-id> --job-status=<job-status>

Examples:

# submit training job on data in Viam Cloud with a Viam-managed training script
viam train submit managed --dataset-id=456 --model-org-id=123 --model-name=MyCoolClassifier --model-type=single_label_classification --model-labels=1,2,3

# submit custom training job with an existing training script in the Registry on data in Viam Cloud
viam train submit custom from-registry --dataset-id=<INSERT DATASET ID> --org-id=<INSERT ORG ID> --model-name=MyRegistryModel --model-version=2 --version=1 --script-name=mycompany:MyCustomTrainingScript  --args=num_epochs=3,model_type=multi_label

# submit custom training job with an uploaded training script on data in Viam Cloud
viam train submit custom with-upload --dataset-id=<INSERT DATASET ID> --model-org-id=<INSERT ORG ID> --model-name=MyRegistryModel --model-type=single_label_classification --model-version=2 --version=1 --path=<path-to-tar.gz> --script-name=mycompany:MyCustomTrainingScript --args=num_epochs=3,labels="'green_square blue_star'"

# get a training job from Viam Cloud based on training job ID
viam train get --job-id=123

# get training job logs from Viam Cloud based on training job ID
viam train logs --job-id=123

# cancel training job in Viam Cloud based on training job ID
viam train cancel --job-id=123

# list training jobs in Viam Cloud based on organization ID and job status
viam train list --org-id=123 --job-status=completed

Command options

Command optionDescriptionPositional arguments
submitSubmits training job on data in the Viam Cloud.managed, custom
getGets a training job from the Viam Cloud based on training job ID.-
logsGets the logs of a training job from the Viam Cloud based on training job ID.-
cancelCancels training job in the Viam Cloud based on training job ID.-
listLists training jobs in Viam Cloud based on organization ID and job status.-
Positional arguments: submit
ArgumentDescriptionPositional Arguments
managedSubmits training job on data in the Viam Cloud with a Viam-managed training script.-
customSubmits custom training job on data in the Viam Cloud.from-registry, with-upload
Position arguments: submit custom
ArgumentDescription
from-registrySubmit custom training job with an existing training script in the registry on data in the Viam Cloud.
with-uploadUpload a draft training script and submit a custom training job on data in the Viam Cloud.
Named arguments
ArgumentDescriptionApplicable commandsRequired?
--dataset-idThe ID of the dataset to train on. To find the dataset ID of a given dataset, go to the DATASETS subtab of the DATA tab on the Viam app and select a dataset. Click in the left-hand menu and click Copy dataset ID.submit managed, submit custom from-registry, submit custom with-uploadRequired
--model-org-idThe organization ID to train and save the ML model in. You can find your organization ID by running viam organizations list or by visiting your organization’s Settings page in the Viam app.submit managed, submit custom with-uploadRequired
--org-idThe organization ID to train and save the ML model in or list training jobs from. You can find your organization ID by running viam organizations list or by visiting your organization’s Settings page in the Viam app.submit custom from-registry, listRequired
--model-nameThe name of the ML model.submit managed, submit custom from-registry, submit custom with-uploadRequired
--model-typeType of model to train. Can be one of single_label_classification, multi_label_classification, object_detection, or unspecified.submit managed, submit custom with-uploadRequired, Optional
--model-labelsLabels to train on. These will either be classification or object detection labels.submit managedRequired
--model-versionSet the version of the submitted model. Defaults to current timestamp if unspecified.submit managed, submit custom from-registry, submit custom with-uploadRequired
--script-nameThe registry name of the ML training script to use for training. If uploading, this sets the name.submit custom from-registry, submit custom with-uploadRequired
--versionThe version of the ML training script to use for training.submit custom from-registry, submit custom with-uploadRequired
--pathThe path to the ML training script to upload.submit custom with-uploadRequired
--job-idThe ID of the training job to get or cancel. You can retrieve this value with train list.get, logs, cancelRequired
--job-statusTraining status to filter for. Can be one of canceled, canceling, completed, failed, in_progress, pending, or unspecified.listRequired
--frameworkFramework of the ML training script to upload, can be tflite, tensorflow, pytorch, or onnx.submit custom with-uploadOptional
--argsPass custom comma-separated arguments to the training script. Example: num_epochs=3,model_type=multi_label. To include whitespace, enclose the value with whitespace in single and double quotes. Example: num_epochs=3,labels="'green_square blue_star'".submit custom from-registry, submit custom with-uploadOptional

version

The version command returns the version of the Viam CLI. To update to the latest version of the CLI, run the installation steps again to download and install the latest version.

viam version

whoami

The whoami command returns the Viam user for an authenticated CLI session, or “Not logged in” if there is no authenticated session.

viam whoami

auth-app

The auth-app command allows you to register, update, and get your web or mobile application (created with the Viam Flutter or TypeScript SDKs) with FusionAuth (the tool Viam uses for authentication and authorization) so that you or other users can log into your app with the same credentials they use to log into the Viam app. The user’s credentials allow them the same permissions to organizations, locations, and machines that they have in the Viam app.

viam auth-app register --org-id=<org-id> --application-name=<application-name> --origin-uris=<origin-uris> --redirect-uris=<redirect-uris> --logout-uri=<logout-uri>
viam auth-app update --org-id=<org-id> --application-id=<application-id> --application-name=<application-name> --origin-uris=<origin-uris> --redirect-uris=<redirect-uris> --logout-uri=<logout-uri>
viam auth-app get --org-id=<org-id> --application-id=<application-id>

Examples:

# register a third party auth application
viam auth-app register --org-id=z1234567-1a23-45a6-a11b-abcdefg1234 --application-name="julias app" --origin-uris=https://test.com,https://test2.com --redirect-uris=https://redirect-url.com--logout-uri=https://logout.com
Info: Successfully registered auth application
{
  "application_id": "1234a1z9-ab2c-1234-5678-bcd12345678a",
  "application_name": "julias app",
  "secret": "supersupersecretsecret"
}

# update a third party auth application
viam auth-app update --org-id=z1234567-1a23-45a6-a11b-abcdefg1234 --application-name="julias app" --application-id=1234a1z9-ab2c-1234-5678-bcd12345678a --redirect-uris=https://test.com,https://test2.com
Info: Successfully updated auth application
{
  "application_id": "1234a1z9-ab2c-1234-5678-bcd12345678a",
  "application_name": "julias app"
}

# get configuration for a third party auth application
viam auth-app get --org-id=z1234567-1a23-45a6-a11b-abcdefg1234 --application-id=1234a1z9-ab2c-1234-5678-bcd12345678

Command options

Command optionDescription
registerRegister an application with FusionAuth
updateUpdate your application
getGet the configuration of the auth application
Named arguments

The org-id and application-id are immutable; they cannot be updated with update after the application is registered.

ArgumentDescriptionApplicable commandsRequired?
--org-idThe organization ID with which to associate this app.register, update, getRequired
--application-nameA display name (of your choice) for your application.register, updateRequired
--application-idThe ID of the application.update, getRequired
--origin-urisAll URIs from which valid logins to FusionAuth can originate from.register, updateRequired for register
--redirect-urisURIs to which FusionAuth will redirect the user upon login.register, updateRequired for register
--logout-uriURI of page to show user upon logout.register, updateRequired for register

Global options

You can pass global options after the viam CLI keyword with any command.

Global optionDescription
--debugEnable debug logging (default: false)