Workspaces

Domains

client.domains manages the domains a workspace classifies its files against. See Domains for the concept, and the API reference for every field.

  • A domain is a two-level taxonomy: a list of classes, each a group and a subgroup with a description written for the classifier.
  • Whose it is: Nace provides some (owner="platform"), and your account can author its own (owner="tenant").
  • Cost: managing domains costs nothing and works at any balance.

A domain version is a draft or published:

StateWhat you can do
DraftEdit it in place, as often as you like, then publish it once. Publishing is one-way.
PublishedGive it to a new workspace. It never changes again: duplicate it and edit the copy.

Nace's own domains never change either: copy them the same way. A workspace is pinned to the version it was made with, so editing a copy never reaches it.

MethodParametersReturnsDescription
create(*, slug, display_name, taxonomy=None)slug: str, display_name: str, taxonomy: dictDomainWriteCreates a draft owned by the account, empty or with the taxonomy given. The slug is lowercase letters, digits and single underscores, up to 64, and can't change.
list(**options)owner: str, status: str, slug: str, limit: int (1 to 200), cursor: strDomainPageOne page of the domains your account sees, the platform's and its own.
iter(**options)owner: str, status: str, slug: strIterator[DomainSummary]Every domain across every page, 200 a page.
get(domain_id)domain_id: strDomainOne domain version with its taxonomy.
update(domain_id, *, display_name=None, taxonomy=None)domain_id: str, display_name: str, taxonomy: dictDomainWriteRenames a draft or replaces its whole taxonomy.
publish(domain_id)domain_id: strDomainWriteFreezes a draft so workspaces can use it by its slug. One-way.
duplicate(domain_id)domain_id: strDomainWriteA draft copy of any domain you see, the platform's included, under a new slug.
  • A taxonomy is a list of classes, {"classes": [...]}. A document that fits no class is labelled as such, not forced into one. Each class has:

    • group and subgroup: lowercase letters, digits and single underscores, up to 64 characters each.
    • description: what the classifier reads.
    • aliases (optional): earlier names.

    If a class doesn't follow these rules, the whole create or update is refused with 422 invalid_request, and nothing is saved.

  • A write returns its validation: create, update, publish and duplicate return a DomainWrite: the saved domain, and a validation of what's wrong with the taxonomy so far. A draft that follows the rules can still be one publish refuses, with domain_validation_failed: one with no classes, or with a class in the reserved group other.

  • Retries: list, iter, get and update are retried. create, publish and duplicate aren't, unless you pass retry: they aren't idempotent, since a retry after the first call landed answers 409 or makes a second copy.

WhenIt raises
A domain_id you can't seeNaceNotFoundError (domain_not_found)
update or publish on a published domainNaceConflictError (domain_not_editable)
update or publish on a platform domainNacePermissionDeniedError
publish with a taxonomy that fails validationNaceUnprocessableEntityError (domain_validation_failed), with the rules to fix in detail
A limit outside 1 to 200, or a domain_id that is empty or holds /, ? or #NaceError, before any request

List domains

list_domains.py
from nace_sdk import NaceClient

with NaceClient() as client:
    page = client.domains.list(owner="platform", status="published")
    for domain in page.items:
        print(domain.slug, domain.version, domain.class_count)

    for domain in client.domains.iter(owner="tenant"):
        print(domain.domain_id, domain.slug, domain.status)

Author and publish a domain

publish_domain.py
draft = client.domains.create(slug="leases", display_name="Leases")
client.domains.update(
    draft.domain.domain_id,
    taxonomy={
        "classes": [
            {"group": "leases", "subgroup": "amendments", "description": "Amendments to a signed lease.", "aliases": []},
        ]
    },
)
published = client.domains.publish(draft.domain.domain_id)
print(published.domain.selectable, published.validation.valid)

Change a published domain

duplicate_domain.py
copy = client.domains.duplicate(published.domain.domain_id)
print(copy.domain.slug, copy.domain.status)  # a draft under a new slug

Create a workspace against a domain

Pass the published domain's slug as domain_slug. See Create a workspace.

workspace_with_domain.py
workspace = client.workspaces.create(name="fy25-leases", domain_slug="leases")
print(workspace.domain_slug, workspace.domain_id)

On this page