Rules & constraints
Troubleshoot errors and understand how Ontology behaves when you hit a limit.
This page covers constraints enforced by the Ontology API, organized by the problem you're trying to solve. If your request failed or something behaved unexpectedly, find your scenario below.
My concept type won't create
You're calling POST /api/v1/ontologies/{id}/concept-types and getting an error.
| What you tried | Why it failed | Error |
|---|---|---|
Reused a key already on this ontology | Keys must be unique per ontology | 409 |
| Used a template ontology ID | Templates are read-only; adopt first | 400 |
| Wrote to an archived ontology | Only status=active ontologies accept writes | 400 |
| Ontology belongs to another org/workspace | Not visible to your principal | 404 |
Good to know:
- Concept types are flat.
parent_idis only for attribute inheritance, not a 4-level display tree. - Live ontologies are workspace-scoped after adopt. Templates have
workspace_id = null.
My attribute won't validate
You're creating or updating a concept and getting 422.
| What you tried | Why it failed | Code |
|---|---|---|
Omitted a required attribute | Required fields must be present | attribute_required |
| Sent an unknown attribute key | Must match the concept type definition | attribute_unknown |
Wrong shape for data_type (e.g. string for number) | Values are type-checked | attribute_type |
Select value not in select_options | Choices are closed | attribute_choice |
multi_select not an array | Must be a list of strings | attribute_type |
Supported data_type values: text, number, boolean, date, select, multi_select.
My relation won't create
You're calling POST /api/v1/ontology/relations.
| What you tried | Why it failed | Error |
|---|---|---|
| Set both or neither source fields | Exactly one of source_document_id / source_concept_id | 422 |
| Document source on a concept-sourced relation type | source_concept_type_id must be null for documents | 422 |
| Target concept type ≠ relation type target | Types must match | 422 |
| File workspace ≠ ontology workspace | Edges stay inside the adopted workspace | 400 |
Second edge under one_to_one / one_to_many from same source | Cardinality violated | 409 |
I can't delete a type or concept
| What you tried | Why it failed | Error |
|---|---|---|
DELETE concept type with live concepts | Blocked; response includes concept_count | 409 |
DELETE relation type with live relations | Blocked; response includes relation_count | 409 |
DELETE concept still used as relation endpoint | Blocked; response includes relation_count | 409 |
There is no silent cascade. Clear instances first, then delete the type.
Versioning and audit trail
| Behaviour | Detail |
|---|---|
POST …/new-version | Archives current ontology, clones types into version+1, status=active |
document_ontology_version | Written once when a document gets its first relation under that ontology; never mutated |
| After version bump | New classifications use the new ontology ID; old docs keep pointing at the prior version |
Relation filter limits
| What you tried | Why it failed | Error |
|---|---|---|
relation_depth outside 1–3 | Hard cap on graph traversal hops when filtering or walking relations — not a limit on how many concept types or instances you can define | 422 |
More hops in the filter string than relation_depth | Path longer than allowed depth | 422 |
Malformed relation= string | Must match rel.Type or rel.Type(attrs) chains | 422 |
Unbounded / variable-length path queries are out of scope. Traversal is capped at 3 hops. Your ontology schema (types, concepts, relations) is otherwise unbounded.
Explicitly out of scope
- Entity deduplication / merge tooling
- Formal inference / reasoning rules
- Graph canvas visualization (list endpoints are enough for a grouped UI)
See the overview for how Ontology composes with workspaces and tags.