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
groupand asubgroupwith 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:
| State | What you can do |
|---|---|
| Draft | Edit it in place, as often as you like, then publish it once. Publishing is one-way. |
| Published | Give 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.
| Method | Parameters | Returns | Description |
|---|---|---|---|
create(*, slug, display_name, taxonomy=None) | slug: str, display_name: str, taxonomy: dict | DomainWrite | Creates 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: str | DomainPage | One page of the domains your account sees, the platform's and its own. |
iter(**options) | owner: str, status: str, slug: str | Iterator[DomainSummary] | Every domain across every page, 200 a page. |
get(domain_id) | domain_id: str | Domain | One domain version with its taxonomy. |
update(domain_id, *, display_name=None, taxonomy=None) | domain_id: str, display_name: str, taxonomy: dict | DomainWrite | Renames a draft or replaces its whole taxonomy. |
publish(domain_id) | domain_id: str | DomainWrite | Freezes a draft so workspaces can use it by its slug. One-way. |
duplicate(domain_id) | domain_id: str | DomainWrite | A 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:groupandsubgroup: 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
createorupdateis refused with422 invalid_request, and nothing is saved. -
A write returns its validation:
create,update,publishandduplicatereturn aDomainWrite: the saveddomain, and avalidationof what's wrong with the taxonomy so far. A draft that follows the rules can still be onepublishrefuses, withdomain_validation_failed: one with no classes, or with a class in the reserved groupother. -
Retries:
list,iter,getandupdateare retried.create,publishandduplicatearen't, unless you passretry: they aren't idempotent, since a retry after the first call landed answers409or makes a second copy.
| When | It raises |
|---|---|
A domain_id you can't see | NaceNotFoundError (domain_not_found) |
update or publish on a published domain | NaceConflictError (domain_not_editable) |
update or publish on a platform domain | NacePermissionDeniedError |
publish with a taxonomy that fails validation | NaceUnprocessableEntityError (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
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
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
copy = client.domains.duplicate(published.domain.domain_id)
print(copy.domain.slug, copy.domain.status) # a draft under a new slugCreate a workspace against a domain
Pass the published domain's slug as domain_slug. See Create a workspace.
workspace = client.workspaces.create(name="fy25-leases", domain_slug="leases")
print(workspace.domain_slug, workspace.domain_id)