Add custom metadata

To store metadata for a machine part, machine, or location you can add custom metadata in the UI or using the Viam SDKs. You can also add custom metadata for organizations using the Viam SDKs.

Prerequisites

A running machine connected to Viam.

Add a new machine on Viam. Then follow the setup instructions to install viam-server or viam-micro-server on the device you’re using for your project and connect to Viam.

Wait until your machine has successfully connected.

Add and update custom machine part metadata

  1. On a machine page, click on the menu next to the machine part.
  2. Select Custom part metadata.
  3. Add the metadata to the JSON object.
  4. Click Save.
import asyncio
import time

from viam.rpc.dial import DialOptions, Credentials
from viam.app.viam_client import ViamClient
from viam.robot.client import RobotClient

# Configuration constants – replace with your actual values
API_KEY = ""  # API key, find or create in your organization settings
API_KEY_ID = ""  # API key ID, find or create in your organization settings
PART_ID = ""  # the ID of the machine part you want to add metadata to


async def connect() -> ViamClient:
    """Establish a connection to the Viam client using API credentials."""
    dial_options = DialOptions(
        credentials=Credentials(
            type="api-key",
            payload=API_KEY,
        ),
        auth_entity=API_KEY_ID
    )
    return await ViamClient.create_from_dial_options(dial_options)

async def main() -> int:

    async with await connect() as viam_client:
        app_client = viam_client.app_client

        await app_client.update_robot_part_metadata(robot_part_id=PART_ID, metadata={
            "TEST_API_KEY": "ABC123",
        })

        return 0

if __name__ == "__main__":
    asyncio.run(main())

For more information, see GetRobotMetadata and UpdateRobotMetadata.

package main

import (
	"context"

	"go.viam.com/rdk/app"
	"go.viam.com/rdk/logging"
)


func main() {
	apiKey := ""
	apiKeyID := ""
	partID := ""


	logger := logging.NewDebugLogger("client")
	ctx := context.Background()

	viamClient, err := app.CreateViamClientWithAPIKey(
		ctx, app.Options{}, apiKey, apiKeyID, logger)
	if err != nil {
		logger.Fatal(err)
	}
	defer viamClient.Close()

	appClient := viamClient.AppClient()

	appClient.UpdateRobotPartMetadata(ctx, partID, map[string]interface{}{
		"TEST_API_KEY": "ABC123",
	})

}

For more information, see GetRobotMetadata and UpdateRobotMetadata.

import { createViamClient } from "@viamrobotics/sdk";

// Configuration constants – replace with your actual values
let API_KEY = "";  // API key, find or create in your organization settings
let API_KEY_ID = "";  // API key ID, find or create in your organization settings
let PART_ID = "";  // the ID of the machine part you want to add metadata to

async function connect(): Promise<any> {
    // Establish a connection to the Viam client using API credentials
    return await createViamClient({
        credentials: {
            type: "api-key",
            authEntity: API_KEY_ID,
            payload: API_KEY,
        },
    });
}

async function main(): Promise<number> {
    const viamClient = await connect();
    const appClient = viamClient.appClient;
    await appClient.updateRobotPartMetadata(PART_ID, {
        TEST_API_KEY: "ABC123",
    });

    return 0;
}

main().catch((error) => {
    console.error("Script failed:", error);
    process.exit(1);
});

For more information, see GetRobotMetadata and UpdateRobotMetadata.

Add and update custom machine metadata

  1. On a machine page, click on the menu in the top-right corner.
  2. Select Custom machine metadata.
  3. Add the metadata to the JSON object.
  4. Click Save.
import asyncio
import time

from viam.rpc.dial import DialOptions, Credentials
from viam.app.viam_client import ViamClient
from viam.robot.client import RobotClient

# Configuration constants – replace with your actual values
API_KEY = ""  # API key, find or create in your organization settings
API_KEY_ID = ""  # API key ID, find or create in your organization settings
MACHINE_ADDRESS = ""  # the address of the machine you want to capture images from


async def connect() -> ViamClient:
    """Establish a connection to the Viam client using API credentials."""
    dial_options = DialOptions(
        credentials=Credentials(
            type="api-key",
            payload=API_KEY,
        ),
        auth_entity=API_KEY_ID
    )
    return await ViamClient.create_from_dial_options(dial_options)

async def connect_machine() -> RobotClient:
    """Establish a connection to the robot using the robot address."""
    machine_opts = RobotClient.Options.with_api_key(
        api_key=API_KEY,
        api_key_id=API_KEY_ID
    )
    return await RobotClient.at_address(MACHINE_ADDRESS, machine_opts)

async def main() -> int:

    async with await connect_machine() as machine:
        machine_id = (await machine.get_cloud_metadata()).machine_id

    async with await connect() as viam_client:
        app_client = viam_client.app_client

        await app_client.update_robot_metadata(robot_id=machine_id, metadata={
            "TEST_API_KEY": "ABC123",
        })

        return 0

if __name__ == "__main__":
    asyncio.run(main())

For more information, see GetRobotMetadata and UpdateRobotMetadata.

package main

import (
	"context"

	"go.viam.com/rdk/app"
	"go.viam.com/rdk/logging"
	"go.viam.com/rdk/robot/client"
	"go.viam.com/utils/rpc"
)


func main() {
	apiKey := ""
	apiKeyID := ""
	machineAddress := ""


	logger := logging.NewDebugLogger("client")
	ctx := context.Background()

	viamClient, err := app.CreateViamClientWithAPIKey(
		ctx, app.Options{}, apiKey, apiKeyID, logger)
	if err != nil {
		logger.Fatal(err)
	}
	defer viamClient.Close()

	machine, err := client.New(
		context.Background(),
		machineAddress,
		logger,
		client.WithDialOptions(rpc.WithEntityCredentials(
			apiKeyID,
			rpc.Credentials{
				Type:    rpc.CredentialsTypeAPIKey,
				Payload: apiKey,
			})),
	)
	if err != nil {
		logger.Fatal(err)
	}

	appClient := viamClient.AppClient()
	metadata, err := machine.CloudMetadata(ctx)
	if err != nil {
		logger.Fatal(err)
	}
	machineID := metadata.MachineID
	appClient.UpdateRobotMetadata(ctx, machineID, map[string]interface{}{
		"TEST_API_KEY": "ABC123",
	})

}

For more information, see GetRobotMetadata and UpdateRobotMetadata.

import { createViamClient, createRobotClient, RobotClient } from "@viamrobotics/sdk";

// Configuration constants – replace with your actual values
let API_KEY = "";  // API key, find or create in your organization settings
let API_KEY_ID = "";  // API key ID, find or create in your organization settings
let MACHINE_ADDRESS = "";  // the address of the machine you want to capture images from

async function connect(): Promise<any> {
    // Establish a connection to the Viam client using API credentials
    return await createViamClient({
        credentials: {
            type: "api-key",
            authEntity: API_KEY_ID,
            payload: API_KEY,
        },
    });
}

async function connectMachine(): Promise<RobotClient> {
    // Establish a connection to the robot using the machine address
    return await createRobotClient({
        host: MACHINE_ADDRESS,
        credentials: {
          type: 'api-key',
          payload: API_KEY,
          authEntity: API_KEY_ID,
        },
        signalingAddress: 'https://app.viam.com:443',
      });
}

async function main(): Promise<number> {
    const viamClient = await connect();
    const appClient = viamClient.appClient;
    const machine = await connectMachine();
    const machineId = (await machine.getCloudMetadata()).machineId;
    await appClient.updateRobotMetadata(machineId, {
        TEST_API_KEY: "ABC123",
    });

    return 0;
}

main().catch((error) => {
    console.error("Script failed:", error);
    process.exit(1);
});

For more information, see GetRobotMetadata and UpdateRobotMetadata.

Add and update custom location metadata

  1. On a location page, click on the menu in the top-right corner.
  2. Select Custom location metadata.
  3. Add the metadata to the JSON object.
  4. Click Save.
import asyncio
import time

from viam.rpc.dial import DialOptions, Credentials
from viam.app.viam_client import ViamClient
from viam.robot.client import RobotClient

# Configuration constants – replace with your actual values
API_KEY = ""  # API key, find or create in your organization settings
API_KEY_ID = ""  # API key ID, find or create in your organization settings
LOCATION_ID = ""  # the ID of the location you want to add metadata to


async def connect() -> ViamClient:
    """Establish a connection to the Viam client using API credentials."""
    dial_options = DialOptions(
        credentials=Credentials(
            type="api-key",
            payload=API_KEY,
        ),
        auth_entity=API_KEY_ID
    )
    return await ViamClient.create_from_dial_options(dial_options)

async def main() -> int:

    async with await connect() as viam_client:
        app_client = viam_client.app_client

        await app_client.update_location_metadata(location_id=LOCATION_ID, metadata={
            "TEST_API_KEY": "ABC123",
        })

        return 0

if __name__ == "__main__":
    asyncio.run(main())

For more information, see GetLocationMetadata and UpdateLocationtMetadata.

package main

import (
	"context"

	"go.viam.com/rdk/app"
	"go.viam.com/rdk/logging"
)


func main() {
	apiKey := ""
	apiKeyID := ""
	locationID := ""


	logger := logging.NewDebugLogger("client")
	ctx := context.Background()

	viamClient, err := app.CreateViamClientWithAPIKey(
		ctx, app.Options{}, apiKey, apiKeyID, logger)
	if err != nil {
		logger.Fatal(err)
	}
	defer viamClient.Close()

	appClient := viamClient.AppClient()
	appClient.UpdateLocationMetadata(ctx, locationID, map[string]interface{}{
		"TEST_API_KEY": "ABC123",
	})

}

For more information, see GetLocationMetadata and UpdateLocationtMetadata.

import { createViamClient } from "@viamrobotics/sdk";

// Configuration constants – replace with your actual values
let API_KEY = "";  // API key, find or create in your organization settings
let API_KEY_ID = "";  // API key ID, find or create in your organization settings
let LOCATION_ID = "";  // the ID of the location you want to add metadata to

async function connect(): Promise<any> {
    // Establish a connection to the Viam client using API credentials
    return await createViamClient({
        credentials: {
            type: "api-key",
            authEntity: API_KEY_ID,
            payload: API_KEY,
        },
    });
}

async function main(): Promise<number> {
    const viamClient = await connect();
    const appClient = viamClient.appClient;
    await appClient.updateLocationMetadata(LOCATION_ID, {
        TEST_API_KEY: "ABC123",
    });

    return 0;
}

main().catch((error) => {
    console.error("Script failed:", error);
    process.exit(1);
});

For more information, see GetLocationMetadata and UpdateLocationtMetadata.

Add and update custom organization metadata

import asyncio
import time

from viam.rpc.dial import DialOptions, Credentials
from viam.app.viam_client import ViamClient
from viam.robot.client import RobotClient

# Configuration constants – replace with your actual values
API_KEY = ""  # API key, find or create in your organization settings
API_KEY_ID = ""  # API key ID, find or create in your organization settings
ORG_ID = ""  # the ID of the organization you want to add metadata to


async def connect() -> ViamClient:
    """Establish a connection to the Viam client using API credentials."""
    dial_options = DialOptions(
        credentials=Credentials(
            type="api-key",
            payload=API_KEY,
        ),
        auth_entity=API_KEY_ID
    )
    return await ViamClient.create_from_dial_options(dial_options)

async def main() -> int:

    async with await connect() as viam_client:
        app_client = viam_client.app_client

        await app_client.update_organization_metadata(org_id=ORG_ID, metadata={
            "TEST_API_KEY": "ABC123",
        })

        return 0

if __name__ == "__main__":
    asyncio.run(main())

For more information, see GetOrganizationMetadata and UpdateOrganizationMetadata.

package main

import (
	"context"

	"go.viam.com/rdk/app"
	"go.viam.com/rdk/logging"
)


func main() {
	apiKey := ""
	apiKeyID := ""
	orgID := ""


	logger := logging.NewDebugLogger("client")
	ctx := context.Background()

	viamClient, err := app.CreateViamClientWithAPIKey(
		ctx, app.Options{}, apiKey, apiKeyID, logger)
	if err != nil {
		logger.Fatal(err)
	}
	defer viamClient.Close()

	appClient := viamClient.AppClient()
	appClient.UpdateOrganizationMetadata(ctx, orgID, map[string]interface{}{
		"TEST_API_KEY": "ABC123",
	})

}

For more information, see GetOrganizationMetadata and UpdateOrganizationMetadata.

import { createViamClient } from "@viamrobotics/sdk";

// Configuration constants – replace with your actual values
let API_KEY = "";  // API key, find or create in your organization settings
let API_KEY_ID = "";  // API key ID, find or create in your organization settings
let ORG_ID = "";  // the ID of the organization you want to add metadata to

async function connect(): Promise<any> {
    // Establish a connection to the Viam client using API credentials
    return await createViamClient({
        credentials: {
            type: "api-key",
            authEntity: API_KEY_ID,
            payload: API_KEY,
        },
    });
}

async function main(): Promise<number> {
    const viamClient = await connect();
    const appClient = viamClient.appClient;
    await appClient.updateOrganizationMetadata(ORG_ID, {
        TEST_API_KEY: "ABC123",
    });

    return 0;
}

main().catch((error) => {
    console.error("Script failed:", error);
    process.exit(1);
});

For more information, see GetOrganizationMetadata and UpdateOrganizationMetadata.