> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ndi.nace.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Domains

> Classification vocabulary management — 6 endpoints

A domain is a taxonomy (classification vocabulary) and a knowledge-graph ontology,
versioned together. Platform domains (`generic`, `financial`, `legal`, `audit`, etc.)
are published and ready to use. Tenant domains are authored by your organization and
visible only to you.

All list routes use **keyset cursor pagination** (`cursor` / `next_cursor`).

***

## Generate domain draft

```
POST /v1/domains/generate
```

Ask the model for an **unsaved** taxonomy and ontology from a free-text domain
description. Cost class: **slow**. Nothing is persisted and no job is created —
edit the draft, then create it with `POST /v1/domains`.

**Request body:**

* **`description`** (required) — What kinds of files belong in this domain.
* **`display_name`** (optional) — Preferred display name; overrides the model's suggestion.
* **`slug`** (optional) — Preferred slug; overrides the model's suggestion.

```bash theme={"dark"}
curl -X POST "$NDI_BASE_URL/v1/domains/generate" \
  -H "X-API-Key: $NDI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "description": "Files produced during an audit engagement: planning memos, risk assessments, working papers, client correspondence, financial statements and supporting evidence. Classify each file by the phase of work and the type of record it represents.",
    "display_name": "Akhan Testing"
  }'
```

**Response:** taxonomy, ontology, `suggested_slug`, `suggested_display_name`, and
a `validation` object (same shape as create/publish). The draft is normalized so
rule R0 and the other publish gates are satisfied.

***

## List domains

```
GET /v1/domains
```

List all domains visible to the caller: platform-owned published domains plus the
tenant's own domains in any status.

**Query parameters:**

* **`owner`** (optional) — `platform` or `tenant`.
* **`status`** (optional) — `draft` or `published`.
* **`cursor`** (optional) — Opaque cursor from `next_cursor`.
* **`limit`** (optional, default 50, max 200)

```bash theme={"dark"}
curl "$NDI_BASE_URL/v1/domains?owner=platform&status=published" \
  -H "X-API-Key: $NDI_API_KEY"
```

**Response:**

```json theme={"dark"}
{
  "items": [
    {
      "domain_id": "550e8400-e29b-41d4-a716-446655440000",
      "slug": "generic",
      "display_name": "Generic",
      "owner": "platform",
      "version": 1,
      "status": "published",
      "parent_slug": null,
      "class_count": 48,
      "selectable": true
    },
    {
      "domain_id": "550e8400-e29b-41d4-a716-446655440001",
      "slug": "audit",
      "display_name": "Audit",
      "owner": "platform",
      "version": 2,
      "status": "published",
      "parent_slug": "generic",
      "class_count": 120,
      "selectable": true
    }
  ],
  "next_cursor": null,
  "total_count": 8
}
```

***

## Get domain

```
GET /v1/domains/{domain_id}
```

Read one domain version with inheritance already resolved. The taxonomy and ontology
include any entries inherited from a parent domain.

**Response:**

```json theme={"dark"}
{
  "domain_id": "550e8400-e29b-41d4-a716-446655440001",
  "slug": "audit",
  "display_name": "Audit",
  "owner": "platform",
  "version": 2,
  "status": "published",
  "parent_slug": "generic",
  "class_count": 120,
  "selectable": true,
  "taxonomy": {
    "classes": [
      {
        "group": "financial",
        "subgroup": "balance_sheet",
        "description": "Balance sheet: assets, liabilities, and equity.",
        "document_type": "BalanceSheet",
        "aliases": []
      }
    ],
    "allow_other": true
  },
  "ontology": {
    "node_types": [{"name": "Organization", "tier": 1, "description": "..."}],
    "edge_types": [{"name": "subsidiary_of", "from_types": ["Organization"], "to_types": ["Organization"], "description": "..."}]
  },
  "published_at": "2026-01-01T00:00:00Z"
}
```

***

## Create domain

```
POST /v1/domains
```

Create a tenant-owned domain in `draft` status. Drafts are editable and not yet
usable by workspaces. Omitting `ontology` copies the platform's generic ontology.

**Request:**

```json theme={"dark"}
{
  "slug": "compliance_2026",
  "display_name": "Compliance 2026",
  "taxonomy": {
    "classes": [
      {
        "group": "regulatory",
        "subgroup": "gdpr",
        "description": "GDPR compliance documentation.",
        "document_type": "RegulatoryDocument",
        "aliases": []
      }
    ],
    "allow_other": true
  }
}
```

**Body fields:**

* **`slug`** (required) — Unique slug for the tenant, slug pattern, max 64 chars. Reserved platform slugs are refused.
* **`display_name`** (required, 1–200 chars) — Human-readable label.
* **`taxonomy`** (required) — The classification vocabulary.
* **`ontology`** (optional) — Knowledge-graph node and edge types. Omit to inherit the platform generic ontology.

**Response (201 Created):**

```json theme={"dark"}
{
  "domain": { ... },
  "validation": {
    "valid": true,
    "errors": [],
    "effective_class_count": 1,
    "effective_node_type_count": 12,
    "effective_edge_type_count": 20
  }
}
```

Every create and update response includes a `validation` block so you know whether
a `publish` call would succeed before you make it.

**Errors:**

* **`reserved_domain_slug`** (409) — Slug is reserved for platform use.
* **`domain_validation_failed`** (422) — Taxonomy or ontology failed validation.

***

## Update domain

```
PATCH /v1/domains/{domain_id}
```

Edit a draft, or spin a published domain into a new draft version.

* Editing a **draft** mutates the draft in place.
* Editing a **published** domain creates version *n+1* as a new draft, leaving version *n* untouched.

Existing workspaces remain pinned to the version they were created with.

**Request:**

```json theme={"dark"}
{
  "display_name": "Compliance 2026 v2",
  "taxonomy": { ... }
}
```

**Body fields:** Any subset of `display_name`, `taxonomy`, `ontology`.

**Response:** Same shape as Create.

***

## Publish domain

```
POST /v1/domains/{domain_id}/publish
```

Freeze a draft and make it selectable by workspaces. Validation must pass; a failing
publish returns `domain_validation_failed` with the full error list.

**Request body:** `{}` (empty)

**Response:** Same shape as Create, with `status: "published"` and `published_at` set.

**Errors:**

* **`domain_validation_failed`** (422) — Taxonomy or ontology failed the publish gate.

***

## Built-in platform domains

The following slugs are reserved and available to every organization:

| Slug                      | Description                      |
| ------------------------- | -------------------------------- |
| `generic`                 | General-purpose categories       |
| `financial`               | Financial document taxonomy      |
| `legal`                   | Legal document taxonomy          |
| `insurance`               | Insurance document taxonomy      |
| `audit`                   | Audit-specific vocabulary        |
| `audit_private_profit`    | Private-sector audit taxonomy    |
| `audit_public_non_profit` | Public/non-profit audit taxonomy |
