---
title: "Importing & Exporting Tags"
description: "Bulk import tags from CSV files and export tag configurations"
source_url: https://ai-ops.com/docs/tags/importing-exporting
---

# Importing & Exporting Tags

You can import and export tag configurations as CSV files. This is useful for bulk-creating tags across devices, migrating configurations between Koios instances, or editing tag settings in a spreadsheet.

## Exporting Tags

### How to Export

There are two ways to export tag configurations:

1. **From the tag table** — select one or more tags using the checkboxes, then click **Export config** in the bulk actions menu. Only the selected tags are exported.
2. **Export all** — if no tags are selected, the export includes every tag in the system.

The export downloads a file named `tags.csv` containing one row per tag.

### What's Included

The CSV contains all configuration fields for each tag — general settings, protocol-specific fields, and advanced options. Every column is included regardless of protocol, so columns that don't apply to a particular tag's protocol will be empty.

> [!NOTE] Config only, not live data
> The export contains static configuration from the database. Live values, status, timestamps, and error states are not included — those come from the live data cache and change every scan cycle.

### CSV Columns

The export includes these columns:

**Core fields:**

| Column | Description |
|--------|-------------|
| `id` | Database ID (primary key) |
| `name` | Tag name (unique) |
| `description` | Optional description |
| `slug` | UUID identifier |
| `enabled` | Whether the tag is active |
| `device` | Parent device ID |
| `usage` | `0` = Input (read-only), `1` = Output (read/write) |
| `range_min` | Minimum expected value |
| `range_max` | Maximum expected value |
| `units` | Engineering units label |
| `decimal_places` | Display precision (0–3) |
| `source_type` | `0` = Device, `1` = Expression, `2` = In Memory |
| `parent` | Folder ID (if organized in folders) |

**Advanced fields:**

| Column | Description |
|--------|-------------|
| `use_lookup_table` | Whether value mapping is enabled |
| `lookup_table` | Value mapping rules as a JSON string |
| `case_insensitive_lookup` | Case-insensitive value matching |
| `reverse_lookup_on_write` | Reverse mapping when writing |
| `test_output_enable` | Manual test value enabled |
| `test_output_value` | Manual test value |
| `write_always` | Write every scan cycle vs only on change |
| `is_redundant` | Uses device set failover |
| `device_set` | Redundant device set ID |

**Protocol-specific fields:**

| Columns | Protocol |
|---------|----------|
| `opcua_namespace`, `opcua_identifier`, `opcua_identifier_type`, `opcua_datatype` | OPC-UA |
| `modbus_register`, `modbus_register_type`, `modbus_data_type`, `modbus_byte_swap`, `modbus_word_swap`, `modbus_bit_number` | Modbus TCP |
| `ethernet_ip_logix_tagname`, `ethernet_ip_logix_tag_type` | EtherNet/IP (Logix) |
| `ethernet_ip_generic_assembly_instance`, `ethernet_ip_generic_byte_offset`, `ethernet_ip_generic_data_type`, `ethernet_ip_generic_bit_number` | EtherNet/IP (Generic CIP) |
| `soap_rdm_device`, `soap_rdm_parameter` | SOAP (RDM) |
| `rest_boss_device_address`, `rest_boss_variable_code`, `rest_boss_variable_type` | REST (BOSS) |
| `sql_query` | Microsoft SQL |
| `expression` | Calculation |

**Audit fields (read-only):**

| Column | Description |
|--------|-------------|
| `created_at` | Creation timestamp |
| `updated_at` | Last modification timestamp |
| `last_modified_by` | User who last modified the tag |

---

## Importing Tags

### How to Import

1. Navigate to the **Tags** page
2. Click the **Import** button in the table toolbar
3. Select a CSV file from your computer
4. Review the preview to verify what will change
5. Click **Confirm Import** to apply the changes

### CSV Format

The import expects a CSV file with column headers matching the export format. You don't need to include every column — only the fields you want to set. At minimum, new tags require a `name`.

> [!TIP] Start from an export
> The easiest way to build an import file is to export your existing tags, edit the CSV in a spreadsheet, and re-import it. The column headers will already be correct.

**How the import determines what to do with each row:**

| Condition | Action |
|-----------|--------|
| `id` column is empty | **Create** a new tag |
| `id` matches an existing tag and fields differ | **Update** the existing tag |
| `id` matches an existing tag and nothing changed | **Skip** the row |
| Row has validation errors | **Error** — row is not imported |

### Example: Creating New Tags

To create new tags, leave the `id` column empty. Provide at least a `name` and `device` (by ID):

```text
id,name,device,enabled,usage,range_min,range_max,units,decimal_places,opcua_namespace,opcua_identifier,opcua_identifier_type,opcua_datatype
,Supply Air Temp,1,True,0,0,100,°C,2,2,ns=2;s=AHU1/SAT,1,7
,Return Air Temp,1,True,0,0,100,°C,2,2,ns=2;s=AHU1/RAT,1,7
,Damper Position,1,True,1,0,100,%,1,2,ns=2;s=AHU1/Damper,1,7
```

### Example: Updating Existing Tags

To update existing tags, include the `id` column with the tag's database ID. Only the fields you include will be checked for changes:

```text
id,name,range_min,range_max,units
42,Supply Air Temp,-20,50,°C
43,Return Air Temp,-20,50,°C
```

### Preview Step

After selecting a file, Koios performs a **dry run** — it processes the CSV without saving anything and shows you exactly what will happen:

- **Summary** — counts of tags that will be created, updated, skipped, or rejected
- **Row details** — click any row to see a field-by-field diff of what will change
- **Diff table** — click **Show Diff Table** for a full-width view of all changes across all rows, with changed fields highlighted

> [!WARNING] Errors block the import
> If any row has a validation error, the entire import is blocked. Fix the errors in your CSV and re-upload. Common errors include duplicate names, missing required fields, and referencing devices that don't exist.

### Validation Rules

The import validates each row against the same rules as the create/update forms:

| Field | Validation |
|-------|------------|
| `name` | Required, max 128 characters, must be unique |
| `description` | Max 128 characters |
| `device` | Must reference an existing device ID |
| `usage` | Must be `0` (Input) or `1` (Output) |
| `range_min` / `range_max` | Must be valid numbers |
| `units` | Max 12 characters |
| `decimal_places` | Integer between 0 and 3 |
| `source_type` | Must be `0` (Device), `1` (Expression), or `2` (In Memory) |
| Protocol fields | Validated against protocol-specific constraints |

**Boolean fields** accept: `True`/`False`, `true`/`false`, `1`/`0`, `yes`/`no`.

**Foreign key fields** (`device`, `parent`, `device_set`) expect integer IDs.

### After Import

Once you confirm the import:

- Tags are created or updated in a single transaction — if anything fails, all changes are rolled back
- An audit event is recorded (e.g. "Imported 15 tags") with your username
- The tag table automatically refreshes to show the updated list
- Imported tags start collecting data on the next scan cycle if they are enabled and their device is running

> [!NOTE] Service pickup delay
> After import, the datacollector detects new or changed tags on its next scan cycle. This typically takes a few seconds. You don't need to restart any services.

---

## Tips

- **Bulk-create tags for a new device** — export one configured tag from that device, duplicate the row in your spreadsheet for each new tag, change the names and addresses, clear the `id` column, and import.
- **Move tags between Koios instances** — export from one instance, adjust `device` IDs to match the target instance's devices, clear the `id` and `slug` columns, and import on the target.
- **Audit trail** — every import creates an event visible on the **Events** page, grouped under a single parent event so you can see what was imported in one action.
- **Read-only columns** — `id`, `slug`, `created_at`, `updated_at`, and `last_modified_by` are ignored on create. You can leave them in the CSV (useful when round-tripping an export) but they won't overwrite system-managed values.
