Atlas API - Libraries
The API for creating, importing and versioning Atlas libraries of shared type definitions.
Overview#
A library is a reusable set of ontology type definitions - entity types, properties, relationship types, data types and functions - that any number of domains can import. Library types are the T-Box you share; domain types are the ones you specialise per site.
This article is written for developers building an integration against Atlas. It covers the library catalog, the ontology surface inside a library, and the call that imports a library into a domain.
Read Atlas API Overview first. It is the canonical reference for the base address and ports, authentication, the RFC-9457 error contract, the JSON serialization rules, pagination, and the draft-session behaviour that changes what a successful write means. This article does not restate any of that; it links to it.
Three things about libraries are worth knowing up front:
- The catalog and the content are scoped differently.
/api/v1/librariesis the catalog./api/v1/branches/{branch}/libraries/{library}/...is the content. See the next section. - Two libraries are installed with Atlas, and both are overwritten on every boot. Editing either is not durable. Everything else Atlas offers is an example you import. See Shipped libraries.
- A library's declared dependencies are write-once. There is no API to add or remove one after creation. See How imports resolve.
Two scopes, and which one is which#
This is the single most common mistake when writing against the library API.
| Surface | Scope | Route |
|---|---|---|
| Library catalog - which libraries exist, create, delete | HEAD (with an optional ?branch= on list and delete) |
/api/v1/libraries |
| Library content - the types inside a library | Branch-scoped, branch in the path, always required | /api/v1/branches/{branch}/libraries/{library}/... |
It is not the other way round. The branch lives in the path for every read and write of library content, exactly as it does for domain content. The catalog is the one that defaults to the checked-out working tree, and ?branch= on the catalog is an opt-in refinement, not the norm.
The practical consequence: if you create a library on feature/x and then GET /api/v1/libraries with no ?branch=, it will not be in the list, because the catalog read fell back to the working tree at HEAD. Your POST did not fail. You looked in the wrong place.
Authentication#
Every library route group calls .RequireAtlasApiAuth(configuration). With Pulse:Auth:Enabled=true - the shipped default - a call without a Pulse-issued bearer whose aud includes Atlas does not succeed.
Every example below sends the bearer. Do the same in your own code. For how to obtain the token, what an unauthenticated call actually returns, and why it may be HTML rather than a JSON 401, see the Authentication section of Atlas API Overview.
TOKEN="<pulse-issued-bearer>"
ATLAS="https://<your-atlas-server>:4552"
Shipped libraries#
One library is embedded in the binary and restored on every start, and it is the only library present on a fresh deployment. atlas-common and isa95-common are listed with it below because they are the examples most often reached for, but both are imported on request like any other.
| Library | Root @id |
rdfs:label |
What it is |
|---|---|---|---|
atlas-core |
urn:atlas:vocab |
Atlas Core Vocabulary | The framework vocabulary: atlas:NodeBase, atlas:EdgeBase, atlas:isTimeAxis, atlas:hasPropertyConfig and friends. Not an ordinary domain library, and its URN base is urn:atlas:vocab:, not urn:atlas:ontology:atlas-core: |
atlas-common |
urn:atlas:ontology:atlas-common |
Atlas Common Ontology | An example, not installed. The shared measurement vocabulary, including the TVQ compound data type, atlas-common:Quality and the generic contains relationship. Imports atlas-core |
isa95-common |
urn:atlas:ontology:isa95-common |
ISA-95 Common Object Model | An example, not installed. The ISA-95 equipment and asset core: the class-side and instance-side hierarchies (Enterprise, Site, Area, and so on) with typed containment. The Material and Personnel models live in a separate isa95-material-personnel. Imports atlas-common |
Two points worth stating explicitly:
- Only
atlas-coreis installed. It is embedded in the binary and restored on every start.atlas-common,isa95-commonand every other library Atlas ships is an example: present in the installation's examples, imported only when you ask for it, and yours to edit or delete afterwards. atlas-templatesandbase-equipmentdo not exist. A script importing either gets404 Library.NotFound.atlas-templateswas an empty placeholder and has been removed; there is nothing to replace it with, because it never contained anything.
Warning: edits to a seed library do not survive a restart. On every boot Atlas compares each file in its shipped seed directory against the copy in your data repository, and force-overwrites yours whenever the bytes differ (
File.Copy(seedFile, targetFile, overwrite: true), logged asUpgraded stale seed library to shipped version: {File}). The seed libraries are system-owned; the shipped seed is the source of truth. The overwritten file is then swept into anAuto-commit: seed datacommit on the checked-out branch by the same startup routine, so the revert becomes part of your model history with no other warning.This applies to
atlas-coreonly. Every other library, includingatlas-commonandisa95-common, is an example you own once you import it, and a library you created yourself is never touched.What to do instead: create your own library and declare
atlas-commonor another shipped library as a dependency. Never editatlas-corein place, and never build a deployment step that patches it.
Where libraries live on disk#
A library is a single file, libraries/{name}.jsonld, inside the ontology git repository (/atlas/config in the platform Compose file). It is not a directory.
The filesystem path is never returned on the wire. The path field that older versions of this API emitted was removed on purpose, along with message. If your client reads response.path, it will get undefined.
Library catalog#
Base path: {ATLAS}/api/v1/libraries
| Method | Path | Description |
|---|---|---|
GET |
/api/v1/libraries |
List libraries. Optional ?branch= |
POST |
/api/v1/libraries |
Create a library |
GET |
/api/v1/libraries/{library} |
Get one library's name and description |
DELETE |
/api/v1/libraries/{library} |
Hard-delete a library. Optional ?branch= |
List libraries#
curl -H "Authorization: Bearer $TOKEN" \
"$ATLAS/api/v1/libraries"
Response - 200 OK
[
{ "name": "atlas-common" },
{ "name": "atlas-core" },
{ "name": "isa95-common", "description": "Modelled on OPC 10030 (OPC Unified Architecture - Common Object Model: ISA-95), which conforms to ANSI/ISA-95.00.02-2010 Part 2 / IEC 62264-2:2013." }
]
Only name and description are on the wire. description is the rdfs:comment on the first owl:Ontology node in the file, not its rdfs:label. It is emitted as null when absent and then, per the global serializer settings, omitted from the JSON entirely - which is why atlas-core and atlas-common have no description key at all above. Do not assume the key is present.
Results are sorted by name.
Scoping the listing to a branch
curl -H "Authorization: Bearer $TOKEN" \
"$ATLAS/api/v1/libraries?branch=feature/site-rollout"
With ?branch= the handler resolves the branch to a commit SHA and reads the library set off that pinned tree, so a library committed only to a non-HEAD branch appears. Without it, the listing is the working tree at HEAD.
An unresolvable branch name does not error. The handler catches the git failure and falls back to the working-tree listing. A typo in
?branch=therefore returns a plausible-looking HEAD list rather than a 404. Confirm the branch exists viaGET /api/v1/branchesbefore trusting a branch-scoped catalog read.
Get one library#
curl -H "Authorization: Bearer $TOKEN" \
"$ATLAS/api/v1/libraries/isa95-common"
Response - 200 OK
{
"name": "isa95-common",
"description": "Modelled on OPC 10030 (OPC Unified Architecture - Common Object Model: ISA-95), which conforms to ANSI/ISA-95.00.02-2010 Part 2 / IEC 62264-2:2013."
}
404 Not Found when the library does not exist, with detail Library '<name>' not found.
This read has no branch parameter. It resolves against the working tree at HEAD. To confirm a library exists on a specific branch, use the branch-scoped catalog list above, or read its content through /api/v1/branches/{branch}/libraries/{library}/entity-types.
There is no message field, and there is no POST /api/sessions endpoint to be pointed at. The current editing-session concept is the branch draft session at /api/v1/branches/{branch}/draft - see Atlas API Overview.
Create a library#
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
"$ATLAS/api/v1/libraries" \
-d '{
"name": "site-common",
"dependencies": ["isa95-common"],
"description": "Types shared across our sites",
"branch": "main"
}'
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Library identifier, and the file name (libraries/{name}.jsonld). Must not already exist |
dependencies |
string[] | No | Names of other libraries this one builds on. Written into the new file's @context as bare sibling references. Write-once - there is no API to change them later |
description |
string | No | Persisted as rdfs:comment on the root owl:Ontology node, and returned by the catalog reads |
branch |
string | No | Target git branch. Omitted or null targets HEAD |
Response - 201 Created
{ "name": "site-common" }
with
Location: /api/v1/libraries/site-common
The 201 body carries name and nothing else.
Errors
| Status | Condition | Detail |
|---|---|---|
400 |
Empty or whitespace name |
Library name cannot be empty |
409 |
Name already in use | Library 'site-common' already exists |
Both are RFC-9457 application/problem+json, not a bare {"message": ...}.
content is accepted by the schema and then thrown away
If you send a content field carrying raw JSON-LD, nothing happens and nothing tells you. The v1 endpoint's request record does not declare content at all, and its mapping to the internal command hard-codes it:
public CreateLibraryCommand ToCommand() =>
new(Name, Dependencies, Content: null, Description, Branch);
The command handler is capable of using supplied content, but the HTTP surface never gives it any. You get the generated scaffold instead of your document, with a 201 and no error. Do not attempt to seed a library's types through the create call. Create the library empty, then author its types through the branch-scoped ontology routes below.
What the generated scaffold contains
The new file is a minimal ontology header:
{
"@context": [
"atlas-core.jsonld",
"isa95-common.jsonld",
{ "site-common": "urn:atlas:ontology:site-common:" }
],
"@id": "urn:atlas:ontology:site-common:library",
"@graph": [
{
"@id": "urn:atlas:ontology:site-common",
"@type": "owl:Ontology",
"rdfs:label": "site-common Library",
"rdfs:comment": "Types shared across our sites"
}
]
}
Three things to note:
atlas-coreis always imported, whether or not you list it. That is why the framework vocabulary is available in every library without being declared. Listing it independenciesis harmless: the handler strips a trailing.jsonldand de-duplicates.- Every type you later create in this library gets the URN
urn:atlas:ontology:site-common:{LocalName}. All five element kinds share that one namespace per scope, so an entity type and a property cannot both be calledTemperaturein the same library. - The URN prefix is normalised but the library's name is not. The prefix is lowercased and spaces become hyphens, while the file name and the catalog
namekeep whatever casing you sent. CreatingSite Commonproduces a library namedSite Common, stored asSite Common.jsonld, whose types areurn:atlas:ontology:site-common:.... Nothing rejects this; it is simply confusing forever after. Send lowercase, hyphen-separated names.
A 201 does not always mean the library is on the branch
Library writes go through the shared write orchestrator, which means the draft-session behaviour described in Atlas API Overview applies. A write that carries outstanding error-severity validation violations lands in the caller's private draft session and does not advance the target branch, signalled only by the Atlas-Validation-Violations response header. Check that header, and publish with POST /api/v1/branches/{branch}/draft/publish when you have one.
Delete a library#
curl -X DELETE -H "Authorization: Bearer $TOKEN" \
"$ATLAS/api/v1/libraries/site-common?branch=main"
204 No Content on success. ?branch= is optional and defaults to HEAD.
Unlike the create and get paths, delete does not pre-check existence at HEAD. This is intended: so a library that lives only on a feature branch can still be deleted on its own branch; existence is checked inside the branch's worktree. A genuinely missing target returns 404 Library.NotFound.
Blocked deletes return 409 with a dependents list
If anything still imports the library, nothing is deleted and you get the delete-blocked problem type:
{
"type": "https://atlas.timebase.io/errors/delete-blocked",
"title": "Delete Blocked",
"status": 409,
"detail": "Cannot delete 'site-common' — it is referenced by 2 libraries and 1 domain.",
"target": { "name": "site-common", "kind": "library" },
"dependents": [
{ "id": "site-north", "name": "site-north", "kind": "library", "referenceType": "library-imports-library" },
{ "id": "site-south", "name": "site-south", "kind": "library", "referenceType": "library-imports-library" },
{ "id": "lonestar", "name": "lonestar", "kind": "domain", "referenceType": "domain-imports-library" }
]
}
referenceType is one of domain-imports-library or library-imports-library. The dependents array is never truncated, so it is safe to render directly to a user.
Branch on the type URI rather than on the status code: a plain name conflict is .../errors/conflict with the same 409.
A third 409: an open draft session. A library delete is refused while the calling identity holds a draft session on the resolved branch, with the detail naming the draft and both exits (publish or discard). Creates, updates and imports are unaffected, because those merge on publish; a deletion has nothing to fix and publish later, so it is never parked in a draft. This one carries the plain .../errors/conflict type with no code and no extensions, so on a DELETE treat that type as "you have an open draft" and confirm with GET /api/v1/branches/{branch}/draft. Only your own draft blocks you.
The dependency scan is wider than "declared dependencies". A domain blocks the delete if any
*.jsonldfile anywhere underdomains/{domain}/(recursive, not justontology.jsonld) has an@contextentry containinglibraries/whose filename matches. A library blocks it if any*.jsonldunderlibraries/resolves a.jsonld@contextreference to the target file. Matching is case-insensitive. This is why you can get a 409 naming a domain you were sure did not import the library: something else in that domain's subtree references it.
Update a library's description#
PUT /api/v1/libraries/{library}?branch={branch}
The description is the only editable piece of a library's metadata. The name is immutable, and more firmly than a domain's: every importing domain carries the library's path and its CURIE prefix, so a rename would break references in two ways at once.
{
"description": "Shared pump and valve types for the bottling plant."
}
The response echoes the description as persisted, trimmed, and null when cleared.
atlas-coreandatlas-commonrefuse this call with a403and aLibrary.ReadOnlyerror. They ship embedded and are restored on every start, so nothing written to them would survive. Every other library, shipped or your own, accepts it.
Library type definitions#
Base path: {ATLAS}/api/v1/branches/{branch}/libraries/{library}
The library ontology surface is symmetric with the domain ontology surface: each of the five kinds is mapped twice, once under domains/{domain} and once under libraries/{library}, with the same handlers, the same request bodies and the same response bodies. For the full field-by-field description of each body, see Atlas API - Ontology; this section gives the routes, the verbs and the library-specific behaviour.
{branch} is required in the path on every one of these routes. A branch name containing / must be percent-encoded (feature%2Fsite-rollout); the endpoints decode it back.
The five resources#
| Kind | Verbs (relative to the base path) | Update verb | Source |
|---|---|---|---|
data-types |
GET, GET /{name}, POST, PUT /{name}, DELETE /{name} |
PUT | |
entity-types |
GET, GET /{name}, POST, PATCH /{name}, DELETE /{name}, plus PUT and DELETE /{name}/properties/{property} |
PATCH | |
properties |
GET, GET /{name}, POST, PATCH /{name}, DELETE /{name} |
PATCH | |
relationship-types |
GET, GET /{name}, POST, PATCH /{name}, DELETE /{name} |
PATCH | |
functions |
GET, GET /{name}, POST, PUT /{name}, DELETE /{name} |
PUT |
If you have an older integration, four renames apply here and correcting only the version prefix is not enough:
| Old | Current |
|---|---|
.../nodes |
.../entity-types |
.../relationships |
.../relationship-types |
PUT .../entity-types/{name}, PUT .../properties/{name}, PUT .../relationship-types/{name} |
PATCH |
| (absent) | the whole .../data-types group |
The verb rule. Entity types, properties and relationship types update with PATCH, a partial merge in which unsent fields are preserved. Data types and functions update with PUT, a full atomic re-emit of the whole definition. Sending the wrong verb does not return 405: it matches no route, and Atlas answers with the single-page application shell as 200 text/html. Check Content-Type before parsing.
data-types is a full ontology resource in its own right, carrying compound types such as TVQ and the isTimeAxis field flag. Historian-bound measurements depend on it. An integration written before mid-2026 almost certainly does not know it exists. Note that its library twins for PUT and DELETE were added late; before that, library data-type edits returned 404.
functions are full CRUD in library scope, not read-only. They always were on the library side. Deleting a function that an instance-map CalculatedStrategy still binds returns the delete-blocked 409 with target.kind = "function" and dependents[].kind = "instanceMap", referenceType = "calculated-strategy".
Reading a library's entity types#
curl -H "Authorization: Bearer $TOKEN" \
"$ATLAS/api/v1/branches/main/libraries/isa95-common/entity-types"
Each entity type is returned as:
{
"uri": "urn:atlas:ontology:isa95-common:Area",
"label": "Area",
"comment": "A physical, geographical, or logical grouping...",
"parentType": "urn:atlas:vocab:NodeBase",
"properties": [ /* PropertyDefinition[] */ ],
"sourceLibrary": null,
"kind": "entity"
}
kind is a camelCase string ("entity" or "dataType"), never an integer. sourceLibrary is the short name of the imported library that declared the type, and is null for types declared in the scope you are reading. Null members are omitted from the JSON entirely.
Creating an entity type in a library#
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
"$ATLAS/api/v1/branches/main/libraries/site-common/entity-types" \
-d '{
"name": "Filler",
"label": "Filler",
"comment": "Bottle filling machine",
"parentType": "Equipment",
"properties": ["Throughput", "Status"]
}'
201 Created returns the created definition in the body, with no Location header (ontology creates do not emit one).
properties is an optional list of existing property local names or full URIs to attach to the new type in the same git commit. It works cross-scope, so a property imported from a dependency library attaches to a type you are declaring here. An unresolvable entry fails the whole create; the type is never half-made.
Attaching a property to a type#
Attachment is addressed under the entity type, not under the property.
# attach - idempotent, cross-scope, 204 No Content
curl -X PUT -H "Authorization: Bearer $TOKEN" \
"$ATLAS/api/v1/branches/main/libraries/site-common/entity-types/Filler/properties/Throughput"
# detach - 204 No Content, 404 when the property is not declared on the type
curl -X DELETE -H "Authorization: Bearer $TOKEN" \
"$ATLAS/api/v1/branches/main/libraries/site-common/entity-types/Filler/properties/Throughput"
This is the answer to "I created a property in the library, why does nothing have it". Creating a property attaches it to nothing unless you pass attachToTypes at create time or attach it explicitly afterwards.
Note the write-side key is attachToTypes (a list); the read-side key on PropertyDefinition is attachedTypes (a list of full URIs). There is no domain field on a property request - that name was retired.
Attachment is a declared relationship. attachedTypes never reports inherited attachments, and a PATCH with an empty attachToTypes list detaches every declared attachment while leaving inherited ones alone.
A bad parentType is not rejected at write time#
If you reference a parent type that is not in this library or any of its dependencies, the create succeeds. The resolver falls back to a library-scoped URI that resolves to nothing.
You find out later, when the domain that imports this library fails to compile. Read the outstanding problems with the validation route below, before you compile.
Validation#
curl -H "Authorization: Bearer $TOKEN" \
"$ATLAS/api/v1/branches/main/libraries/site-common/validation"
A read-only, side-effect-free run of the validation pipeline over the library, returning every outstanding violation and a WarningCount. It compiles nothing and caches nothing.
This is the actionable half of warn-on-save. A save that persists with error-severity violations gives you only a count, in the Atlas-Validation-Violations response header; this route gives you the list. It is the first thing to call when a library write succeeded but something downstream is wrong.
Rule IDs are O-A* and O-B* for ontology rules, I-A* and I-B* for instance rules. If a document quotes a rule name in any other shape, it is invented.
The read is draft-aware with no extra parameters: the owner of a draft session that is strictly ahead of the target sees their own in-progress breakage, everyone else sees the target branch.
Importing a library into a domain#
A library does nothing until a domain imports it. The imports resource is branch-scoped and lives under the domain.
| Method | Path | Response |
|---|---|---|
GET |
/api/v1/branches/{branch}/domains/{domain}/imports |
200 with a JSON array of library name strings |
POST |
/api/v1/branches/{branch}/domains/{domain}/imports |
201 with { "domain": "...", "library": "..." } |
DELETE |
/api/v1/branches/{branch}/domains/{domain}/imports/{library} |
204 No Content |
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
"$ATLAS/api/v1/branches/main/domains/lonestar/imports" \
-d '{ "library": "isa95-common" }'
The body is { "library": "<name>" } and nothing else.
Errors
| Status | Condition | Detail |
|---|---|---|
404 |
Domain does not exist | Domain '<name>' not found |
404 |
Domain has no ontology.jsonld |
Domain '<name>' has no ontology.jsonld |
404 |
Library does not exist | Library '<name>' not found |
409 |
Already imported | Library '<name>' already imported |
Then rebuild the compiled world with PUT /api/v1/branches/{branch}/domains/{domain}/world.
The domain file on disk is ontology.jsonld. It is not schema.jsonld; any repository tree diagram showing that name is wrong.
How imports resolve#
This resource is not a package manager. What it does provide:
- An import is a plain relative file reference. A domain importing a library appends
"../../libraries/{name}.jsonld"to its ontology's@context. A library importing a sibling library appends the bare"{name}.jsonld". The read side recovers the names by taking the filename without extension. - No version is recorded anywhere. There is no pinning, no range syntax, no lock file. An import always resolves to whatever that file contains on the branch you are reading.
- Resolution is by bare name. Case-insensitive on the delete-guard scan; exact on the
@contextstring when checking for a duplicate import. - The closure is transitive and is loaded at compile time. A library reachable only through another imported library is still loaded, and is still compared for staleness.
- A URN collision across the closure is last-writer-wins. Because all five element kinds share one URN namespace per scope, two libraries that both declare
urn:atlas:ontology:x:Temperatureare indistinguishable to the loader. - Dependencies are write-once.
Application/Libraries/contains exactlyCreateLibraryCommand(Handler),DeleteLibraryCommand(Handler),GetAllLibrariesQuery(Handler)andGetLibraryInfoQuery(Handler). There is no add-dependency or remove-dependency command, and no route mounts one. If you omit a dependency at create time, your options are to editlibraries/{name}.jsonldin the git repository directly, or to delete and recreate the library.
The /app twin is not a contract#
If you watch network traffic from the Atlas user interface you will see /app/libraries and /app/branches/{branch}/libraries/{library}/..., not /api/v1/.... Those are the same handlers behind the same bodies, but they are the private browser plane: cookie authentication, admin-gated mutations, excluded from the published API documents. They are not a public contract and can change without notice.
Integrate against /api/v1. See Atlas API Overview for the full surface list.
Troubleshooting#
| Symptom | Likely cause | What to do |
|---|---|---|
My edits to atlas-core disappeared after a restart |
The seed library is force-overwritten from the shipped copy on every boot and the revert is auto-committed | Never edit atlas-core. Create your own library instead. Imported libraries such as atlas-common and isa95-common are yours and are not overwritten |
POST /api/v1/libraries returns 409 |
A library with that name already exists at HEAD | Call GET /api/v1/libraries to check. The existence check looks at HEAD rather than the branch you are writing to, so pick a name that is unused across every branch |
POST /api/v1/libraries returned 201 but the library is not in GET /api/v1/libraries |
You created it on a branch; the catalog list defaults to HEAD | Pass ?branch=<your-branch> on the list. If it is still missing, check the Atlas-Validation-Violations header on the create response and GET /api/v1/branches/{branch}/draft |
I sent content on create and got the empty scaffold back |
The endpoint hard-codes Content: null; content is ignored |
Create the library empty, then author its types through the branch-scoped ontology routes |
My client reads response.path and gets undefined |
path was removed from every library response, along with message |
Use name. A library is one file, libraries/{name}.jsonld, but that is not on the wire |
A library route returns 200 text/html instead of JSON |
The path matched no route and the single-page-application fallback answered it. Usually nodes instead of entity-types, relationships instead of relationship-types, PUT where PATCH is expected, or a missing /branches/{branch} segment |
Check Content-Type before parsing, then check the route against the tables above |
GET /api/v1/libraries/{library}/entity-types returns HTML |
Library content is branch-scoped; there is no non-branch-scoped content route | Use /api/v1/branches/{branch}/libraries/{library}/entity-types |
| A type created in a library does not appear in a domain | The domain has not imported the library, or has not been recompiled since | POST /api/v1/branches/{branch}/domains/{domain}/imports with { "library": "<name>" }, then PUT /api/v1/branches/{branch}/domains/{domain}/world |
POST .../imports returns 404 Library.NotFound for a library I can see |
The import check reads the working tree at HEAD, not your branch | Confirm the library exists at HEAD, or merge your branch first |
POST .../imports returns 404 naming atlas-templates, base-equipment or opc10030-isa95-common |
None of those ships. The first was removed, the second never existed, the third is now isa95-common |
Use isa95-common, or list what is available |
A parentType pointing at a type in another library was accepted, then the domain failed to compile |
Bad parent references are not rejected at write time; they fall back to an unresolvable scoped URI | GET /api/v1/branches/{branch}/libraries/{library}/validation, then either declare the parent locally or add the dependency. Dependencies are write-once, so this may mean recreating the library |
DELETE /api/v1/libraries/{library} returns 409 naming a domain I am sure does not import it |
The scan inspects the @context of every *.jsonld under domains/{domain}/ recursively, not just ontology.jsonld |
Read the dependents array in the problem body; it lists exactly what blocks you and is never truncated |
My DELETE handler treats 409 as "name already exists" |
A blocked delete uses the distinct type .../errors/delete-blocked and carries target and dependents |
Branch on the type URI, not the status code |
?branch=typo returned a library list that looks like HEAD |
An unresolvable branch falls back to the working-tree listing rather than erroring | Verify the branch with GET /api/v1/branches first |
| My library name has capitals and its type URNs do not match it | The URN prefix is lowercased and space-hyphenated; the file name and catalog name are not |
Use lowercase, hyphen-separated names. Nothing enforces it |
Related articles#
- Atlas API Overview
- Atlas API Overview - Ontology
- Atlas API Overview - Domains
- Atlas API Overview - Instance Maps
- Atlas Libraries
- Timebase Atlas Key Concepts