---
title: "Import tenants from CSV file"
method: POST
path: "/api/v1/tenants/import/csv"
tags: ["tenants"]
---

# Import tenants from CSV file

`POST /api/v1/tenants/import/csv`

Import tenants from a CSV file using upsert semantics.

Expected CSV format:
- tenant_key (required): Unique tenant identifier
- tenant_name (optional): Human-readable name
- group_names (optional): Comma-separated list of group names
- Additional columns can be mapped to attributes via attribute_columns

Creates new tenants and updates existing ones with new name/groups.
Groups are added additively (not replaced) and auto-created if needed.

Optionally processes attribute columns: values are validated against
attributes.yaml, stored additively, and validation errors are non-fatal.

RLS: Filtered to current client (ClientRLSDB).

Raises:
    ValidationError: If CSV format is invalid (400)
    TenantCreationNotAllowedError: If tenancy type is NONE (400)

## Query parameters

- `source` string, nullable

## Headers

- `X-Kater-CLI-ID` string, nullable

## Response `200`

Successful Response

- ImportTenantsResponse — Response model for tenant import operation.
  - `attribute_errors` ImportAttributeError[] — Non-fatal attribute validation errors during import
    - `attribute` string, required — Attribute name that failed
    - `error` string, required — Error message
    - `tenant_key` string, required — Tenant key for which attribute processing failed
    - `value` string, required — Value that caused the error
  - `errors` ImportTenantError[] — Tenant-specific errors
    - `code` string, required — Error code
    - `message` string, required — Error message
    - `tenant_key` string, required — Tenant key that failed
  - `groups_created` string[] — Groups that were auto-created
  - `total_found` integer, required — Unique tenant keys found in source
  - `total_imported` integer, required — New tenants created
  - `total_updated` integer, required — Existing tenants updated

## Other responses

- `400` — Bad Request
- `401` — Unauthorized
- `422` — Validation Error

## Changes

- **2026-02-26** `bef1f3e205dd` — 3 breaking, 4 info
  - response property `errors` list-of-types was widened by adding types `array` to media type `application/json` of response `400`
  - response property `errors` list-of-types was widened by adding types `array` to media type `application/json` of response `401`
  - response property `errors` list-of-types was widened by adding types `array` to media type `application/json` of response `422`
  - added the new optional `header` request parameter `X-Kater-CLI-ID`
  - …3 more
- **2026-01-29** `5f4f08ff6556` — 1 warning, 4 info
  - removed the optional property `detail` from the response with the `422` status
  - added the optional property `errors` to the response with the `422` status
  - added the required property `code` to the response with the `422` status
  - added the required property `message` to the response with the `422` status
  - …1 more

[Change history](https://skmtc.dev/kater-ai/apis/kater-api/changes/api/v1/tenants/import/csv/post.md)

---

[API](https://skmtc.dev/kater-ai/apis/kater-api.md) · [All operations](https://skmtc.dev/kater-ai/apis/kater-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/kater-ai/kater-api/revisions/6a140b82e07c/schema)
