---
title: "Importing & Exporting Models"
description: "Bulk import and export AI model and binding configurations as CSV"
source_url: https://ai-ops.com/docs/models/importing-exporting
---

# Importing & Exporting Models

You can import and export AI model configurations — including their bindings — as CSV files. This is useful for migrating models between Koios instances, bulk-editing binding settings in a spreadsheet, or backing up model configurations before making changes.

> [!NOTE] Configuration only — model files are separate
> Import and export covers model settings and binding configurations, not the model files themselves (ONNX/TFLite). Model files must be uploaded separately through the model files page. See [Managing Model Files](https://ai-ops.com/docs/models/model-files.md).

## How Models and Bindings Relate

Each AI model has a set of **bindings** — input bindings that map tags to model inputs, and output bindings that map model outputs back to tags. When you export models, Koios exports both the model settings and all of their bindings together.

The export produces a **ZIP file** containing two CSV files:

| File | Contents |
|------|----------|
| `models.csv` | One row per model — general settings, inference config, and scan options |
| `bindings.csv` | One row per binding — tag assignments, normalization, failure detection, and output settings |

---

## Exporting Models

### How to Export

There are two ways to export model configurations:

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

The export downloads a file named `models_export.zip`.

### What's Included

Both CSVs contain all configuration fields. Columns that don't apply to a particular model or binding will be empty.

> [!NOTE] Config only, not live data
> The export contains static configuration from the database. Live inference values, status, and error states are not included.

### Model CSV Columns

**Core fields:**

| Column | Description |
|--------|-------------|
| `id` | Database ID (primary key) |
| `slug` | UUID identifier |
| `name` | Model name (unique) |
| `description` | Optional description |
| `enabled` | Whether the model is actively running inference |

**Inference settings:**

| Column | Description |
|--------|-------------|
| `output_application` | `0` = Absolute, `1` = Relative |
| `output_mode` | `0` = Continuous, `1` = Discrete |
| `scan_rate` | Inference interval in seconds (0.1–3600) |
| `sample_rate` | Historical data resample rate in seconds |
| `on_demand` | Whether on-demand inference is enabled |
| `on_demand_timeout` | On-demand timeout in seconds (0.5–30) |
| `memory_only` | Store predictions in the live data cache only (skip time-series database) |
| `log_level` | Diagnostic log level (INFO, DEBUG, WARNING, ERROR) |

**References:**

| Column | Description |
|--------|-------------|
| `aiopmodel_file` | Active model file (read-only — set by file upload) |
| `scan_group` | Scan group ID (for synchronized execution) |
| `remote_enable_tag` | Tag ID for remote enable/disable control |
| `parent` | Folder ID (if organized in folders) |

**System-managed fields (read-only):**

| Column | Description |
|--------|-------------|
| `inputs` | Number of model inputs (set by model file metadata) |
| `outputs` | Number of model outputs (set by model file metadata) |
| `created_at` | Creation timestamp |
| `updated_at` | Last modification timestamp |
| `last_modified_by` | User who last modified the model |

> [!WARNING] Locked fields
> The `inputs`, `outputs`, and `aiopmodel_file` fields are set automatically when a model file is uploaded. They cannot be changed through import — any values in these columns are ignored.

### Binding CSV Columns

**Core fields:**

| Column | Description |
|--------|-------------|
| `id` | Database ID (primary key) — **required** for binding import |
| `slug` | UUID identifier |
| `aiopmodel` | Parent model ID |
| `usage` | `0` = Input, `1` = Output |
| `binding_order` | Position in the input or output list (0-based) |
| `name` | Binding name (from model file metadata) |
| `description` | Optional description |
| `tag` | Assigned tag ID (required for inputs, optional for outputs) |

**Normalization:**

| Column | Description |
|--------|-------------|
| `normalization_type` | `0` = None, `1` = Min-Max, `2` = Symmetric, `3` = Z-Score |
| `normalization_source` | `0` = Tag Range, `1` = Custom |
| `custom_minimum` | Custom min value (when source is Custom) |
| `custom_maximum` | Custom max value (when source is Custom) |
| `custom_mean` | Custom mean (for Z-Score normalization) |
| `custom_std` | Custom standard deviation (for Z-Score normalization) |

**Calibration:**

| Column | Description |
|--------|-------------|
| `gain` | Linear multiplier (default `1.0`). Cannot be zero. See [Calibration (Gain & Bias)](https://ai-ops.com/docs/models/assigning-bindings.md#calibration-gain--bias). |
| `bias` | Linear offset added after gain (default `0.0`). |

**Output settings:**

| Column | Description |
|--------|-------------|
| `output_index` | 1-based output tensor index |
| `clamp_output` | Clamp output values to the normalization range |
| `max_upper_step` | Maximum output step increase per scan |
| `max_lower_step` | Maximum output step decrease per scan |

**Failure detection:**

| Column | Description |
|--------|-------------|
| `failure_range_mode` | `0` = Disabled, `1` = Custom, `2` = Normalization Range |
| `custom_failure_minimum` | Custom failure range minimum |
| `custom_failure_maximum` | Custom failure range maximum |
| `failure_evaluation` | `0` = Any, `1` = Latest, `2` = Average |
| `failure_debounce` | Consecutive failing scans before the model enters a failed state |
| `consider_stale_allowed_samples` | Allowed missed input samples before failure |
| `recovery_hysteresis` | Recovery hysteresis percentage (0–50%) |

**Rate-of-change detection:**

| Column | Description |
|--------|-------------|
| `roc_enabled` | Whether rate-of-change detection is enabled |
| `roc_threshold` | ROC threshold value |
| `roc_threshold_mode` | `0` = Units per minute, `1` = Percent of range per minute |
| `roc_direction` | `0` = Rising, `1` = Falling, `2` = Both |
| `roc_window` | ROC measurement window in seconds |

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

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

---

## Importing Models

### How to Import

1. Navigate to the **Models** page
2. Click the **Import** button in the table toolbar
3. Select a file — either a ZIP (with `models.csv` and/or `bindings.csv`) or a single CSV
4. Review the preview to verify what will change
5. Click **Confirm Import** to apply the changes

### File Formats

The import accepts three file formats:

| Format | Contents |
|--------|----------|
| **ZIP file** | Contains `models.csv` and/or `bindings.csv` — both are processed together |
| **Single CSV (models)** | Detected automatically by column headers — creates or updates models |
| **Single CSV (bindings)** | Detected automatically by column headers — updates bindings only |

Koios auto-detects whether a CSV contains models or bindings based on the column headers.

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

### Models: Create or Update

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

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

### Bindings: Update Only

> [!WARNING] Bindings cannot be created through import
> Bindings are created automatically when you upload a model file — they reflect the model's input and output structure. Import can only **update** existing bindings (for example, assigning tags, changing normalization, or adjusting failure detection settings). If a binding row has no `id` or references a binding that doesn't exist, it will be rejected.

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

| Condition | Action |
|-----------|--------|
| `id` matches an existing binding and fields differ | **Update** the existing binding |
| `id` matches an existing binding and nothing changed | **Skip** the row |
| `id` is empty or doesn't match a binding | **Error** — bindings cannot be created |

### Import Order

When importing a ZIP with both files, Koios processes models first, then bindings. This ensures any new models exist before their bindings are updated.

### Example: Creating New Models

To create new models, leave the `id` column empty. Provide at least a `name`:

```text
id,name,description,enabled,scan_rate,sample_rate,output_application,output_mode,log_level
,AHU Supply Air Model,Predicts supply air temperature,False,1.0,1.0,0,0,INFO
,Chiller Efficiency Model,Estimates COP from sensor data,False,5.0,5.0,0,0,INFO
```

> [!TIP] New models need a model file
> After importing new models, upload a model file (ONNX or TFLite) to each one. This creates the bindings and sets the input/output count. Then export again, edit the bindings CSV to assign tags and configure normalization, and re-import.

### Example: Bulk-Editing Binding Normalization

Export your models, then edit the bindings CSV to set normalization for all input bindings at once:

```text
id,normalization_type,normalization_source,custom_minimum,custom_maximum
501,1,1,-20,50
502,1,1,0,100
503,1,1,0,500
```

This sets Min-Max normalization with custom ranges on three bindings.

### Example: Assigning Tags to Bindings

```text
id,tag
501,42
502,43
503,44
```

This assigns tag IDs 42, 43, and 44 to the three input bindings.

### Preview Step

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

- **Summary** — counts of items 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, with changed fields highlighted

If the import includes both models and bindings (from a ZIP), the preview shows results for both.

> [!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 model names, missing required fields, and attempting to create bindings (instead of updating existing ones).

### Validation Rules

**Model validation:**

| Field | Validation |
|-------|------------|
| `name` | Required, max 128 characters, must be unique |
| `description` | Max 256 characters |
| `scan_rate` | Number between 0.01 and 3600 |
| `sample_rate` | Number between 0.01 and 3600 |
| `on_demand_timeout` | Number between 0.5 and 30 |
| `output_application` | Must be `0` (Absolute) or `1` (Relative) |
| `output_mode` | Must be `0` (Continuous) or `1` (Discrete) |
| `log_level` | Must be INFO, DEBUG, WARNING, or ERROR |

**Binding validation:**

| Field | Validation |
|-------|------------|
| `id` | Required — must match an existing binding |
| `tag` | Must reference an existing tag ID |
| `normalization_type` | Must be `0` (None), `1` (Min-Max), `2` (Symmetric), or `3` (Z-Score) |
| `normalization_source` | Must be `0` (Tag Range) or `1` (Custom) |
| `recovery_hysteresis` | Number between 0 and 50 |

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

**Foreign key fields** (`tag`, `aiopmodel`, `scan_group`, `remote_enable_tag`, `parent`) expect integer IDs.

### After Import

Once you confirm the import:

- Models and bindings are created or updated in a single transaction — if anything fails, all changes are rolled back
- An audit event is recorded (e.g. "Imported 5 models") with your username
- The model table automatically refreshes to show the updated list
- Updated models pick up changes on the next inference cycle if they are enabled

> [!NOTE] Service pickup delay
> After import, the predict engine detects configuration changes within a few seconds. You don't need to restart any services.

---

## Tips

- **Typical workflow for new models** — create models via import (or the UI), upload model files to generate bindings, export the bindings, bulk-edit tag assignments and normalization in a spreadsheet, then re-import the bindings.
- **Bulk-edit normalization** — export, filter the bindings CSV to input bindings (`usage` = `0`), set `normalization_type`, `normalization_source`, and custom range columns, then import just the bindings CSV.
- **Move models between Koios instances** — export from one instance, clear the `id` and `slug` columns in the models CSV (and the `id`, `slug` columns in the bindings CSV), adjust any `tag` and `scan_group` IDs to match the target instance, and import on the target. You'll also need to re-upload the model files.
- **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`, `inputs`, `outputs`, `aiopmodel_file`, `created_at`, `updated_at`, and `last_modified_by` are ignored on model create. You can leave them in the CSV but they won't overwrite system-managed values.
