Docs/Timebase Components/Naming Conventions for Atlas Models
AtlasReference

Naming Conventions for Atlas Models

Atlas does not enforce a naming style. Almost nothing here is validated.

Updated 17 Oct 2026Timebase Docs

Overview#

This is the canonical naming reference for Atlas models. It covers every element kind, the one naming rule that blocks a save, and the two that decide whether a query finds your data.

A name is the most permanent decision you make about an element, because the local name is locked after creation. Label and description stay editable; the name does not. Changing a name means creating a replacement and deleting the original.

The conventions below are the ones the supplied libraries follow. Your model sits alongside those libraries in the same namespace, so following them keeps your model reading consistently against the vocabulary it imports.


The convention, by element kind#

Kind Style Shipped examples Why
Entity type PascalCase, singular noun Folder, Enterprise, ProcessCell, EquipmentModule A type names one thing, not a collection. Pump, never Pumps.
Property type PascalCase, noun phrase Description, Timestamp, Value, Quality, UOM, Format Reads as an attribute of the thing that carries it.
Data type PascalCase, noun TVQ Same as entity types. Acronyms stay upper case.
Relationship type camelCase, verb phrase contains, connectsTo, relatesTo, sameAs, enterpriseContains Reads as a sentence in a query: (pump)-[:connectsTo]->(tank).
Function PascalCase, verb phrase - Names an operation. ConvertFahrenheitToCelsius.
Domain / library lower-case-with-hyphens atlas-core, atlas-common, isa95-equipment Atlas applies this for you; see below.

The single most important line in that table is the relationship row. Relationships are the one kind that is not PascalCase. Every relationship in every shipped library is camelCase, without exception.

If you read atlas-core, you will see camelCase names that look like they break the property rule - fieldSequence, timeAxisField, traversalProperty, sourceField, asymmetric. Those are owl:AnnotationProperty entries: Atlas's own internal meta-vocabulary, describing how the modelling machinery works. They are not property types you author or attach to your own entities, and they are not a precedent for naming yours. Compare them with atlas-common, which is the layer holding the property types you actually use, and where every one is PascalCase: Timestamp, Value, Quality, UOM.

Watch the leading capital. A relationship type starts lower case, always. PumpFeedsTank is wrong on that count alone: every relationship in every shipped library begins with a lower-case letter. Use pumpFeedsTank if the relationship really is specific to that pair of types, or reuse connectsTo if it is not.

Why relationships read differently#

The convention is not arbitrary. Entity types and properties are things; relationships are statements about things. In a Cypher query the difference is visible:

MATCH (line:ProductionLine)-[:contains]->(unit:Unit)
RETURN line, unit

ProductionLine and Unit are nouns in type position. contains is a verb in predicate position. This follows ordinary RDF and OWL practice, where classes are capitalised nouns and properties are lowerCamelCase, and it is the convention OWL's own vocabulary uses (owl:Class, rdfs:subClassOf, owl:onProperty).

Two kinds of relationship name, and the rule for choosing#

Relationships come in two flavours, and they are named differently. Getting this distinction right is the whole of relationship naming.

A general, reusable relationship gets a bare camelCase verb. These are meant to be used between many different pairs of types, so the name must not mention any of them:

  • contains - used for every containment in the shipped libraries, from Enterprise down to ControlModule.
  • connectsTo, relatesTo, sameAs - the other three shipped generics.

A specialisation that narrows its endpoints leads with its source. The pattern is {source}{Verb}{Target}, still camelCase, still starting lower case. The shipped OPC 10030 library does exactly this: enterpriseContains is a specialisation of atlas-common:contains whose Source is restricted to Enterprise. Atlas's own UI describes the same pattern with the examples fillerHasFlowTotalizer and fillingAreaContainsFiller.

So a relationship name that embeds its endpoints is correct when the relationship genuinely is endpoint-specific, and wrong only when it is applied to something meant to be reusable. The question to ask is: would a second pair of types want to use this relationship? If yes, name the verb alone. If no, lead with the source.

The UI will suggest a name, and you should usually lower-case its first letter. When you pick a base and endpoints, Atlas auto-fills the Name field as source + verb + target, taking each endpoint's type name verbatim. Because type names are PascalCase, the suggestion arrives as FillerHasFlowTotalizer with a leading capital, while the shipped libraries and the documented convention both use fillerHasFlowTotalizer. The suggestion stops updating as soon as you edit the field, so change it before you save - the name is locked afterwards.

Naming the inverse so it reads both ways#

A relationship type carries an optional asymmetric inverse label. The shipped contains declares containedIn. Name both halves so each reads correctly with its own subject first:

  • contains / containedIn - "line contains unit", "unit containedIn line".
  • feeds / fedBy - "pump feeds tank", "tank fedBy pump".
  • connectsTo - symmetric in practice, so no inverse is needed.

The one rule that blocks a save#

All five element kinds share a single URN namespace per domain or library. A name can be used only once across every kind in that scope.

So a domain that already has an entity type Tank cannot also have a property type Tank. The second write is rejected with HTTP 409 and error code {Kind}.KeyCollision:

Cannot create Property 'Tank': the key 'urn:atlas:ontology:brewery:Tank' is already
used by a Type. All element kinds (Types, Properties, Relationships, Data Types, Functions)
share one URN namespace per domain.

The collision guard runs before the same-kind duplicate check, so a clash with a different kind reports KeyCollision, while a genuine duplicate of the same kind reports {Kind}.AlreadyExists.

The per-kind conventions above avoid most collisions on their own: a singular PascalCase noun for the type and a camelCase verb for the relationship cannot collide. The case to watch is an entity type and a property type, because both are PascalCase nouns. Qualify the property where it would otherwise collide: entity Motor alongside property MotorPowerRating, not property Motor.


The two rules that decide whether a query finds your data#

1. Names are case-sensitive#

Comparison is case-sensitive everywhere, including property access in Cypher, so r.flowrate does not match flowRate and the column comes back empty.

Pick a casing and apply it consistently. This is the single strongest practical argument for following the shipped convention rather than your own: when you read atlas-common:Timestamp in a library and type Timestamp in your query, they match because both follow one rule.

2. Domain and library names are transformed for you#

The writers lower-case the name and replace spaces with hyphens before minting the URN prefix. A domain created as Plant Model becomes:

urn:atlas:ontology:plant-model:

Not plantmodel, and not Plant_Model. Spaces become hyphens, never underscores.

Type the name in its final form yourself - plant-model - so the name you enter is the name you see in every URN afterwards. Otherwise you will search for a prefix that does not exist.

Note on the Name field's own help text. The field describes itself as the local URN segment, and says it accepts letters, digits and underscores. That describes what the local name of a type may contain. It does not override the hyphenation applied to domain and library names, which are a different scope.


Namespaces and prefixes#

Each domain and library owns a URN scope, and local names are appended verbatim by string concatenation:

Scope URN form
Domain urn:atlas:ontology:<domain-name>:<LocalName>
Library urn:atlas:library:<library-name>:<LocalName>
Atlas meta-vocabulary urn:atlas:vocab, conventionally prefixed atlas:

When you reference imported vocabulary, use the library's prefix rather than retyping a full URN: atlas-common:Timestamp, isa88-physical:ProcessCell, atlas:NodeBase. It is shorter, it survives a prefix change, and it makes the provenance of every type visible at a glance - which of these came from a standard, and which you invented.


Naming as documentation#

Two habits repay themselves quickly.

Let the name say the kind. Reading Unit, contains and TVQ in a model, you can tell without looking them up that the first is a thing, the second is a statement, and the third is a structured value. That is only true if the conventions hold everywhere.

Do not encode the hierarchy into names. SiteAreaProcessCell is not a better name than ProcessCell. The containment relationship already records where it sits, and a name that hard-codes one position stops the type being reusable anywhere else. This is the naming form of the mistake described in Modeling Best Practices: baking structure into identity.


Quick reference#

Entity type        PascalCase singular noun      Pump, ProcessCell, StorageUnit
Property type      PascalCase noun phrase        FlowRate, MotorPowerRating, Quality
Data type          PascalCase noun               TVQ, PidSetpoint
Relationship type  camelCase verb phrase         contains, connectsTo, feeds
  (specialisation)   camelCase source-led          enterpriseContains, fillerHasFlowTotalizer
Function           PascalCase verb phrase        ConvertFahrenheitToCelsius
Domain / library   lower-case-with-hyphens       plant-model, acme-equipment

Three rules to remember beyond the table:

  1. One namespace per scope across all five kinds - a name is spent once.
  2. Names are locked after creation, and matched case-sensitively.
  3. For relationships: a bare camelCase verb when it is reusable, {source}{Verb}{Target} when it is endpoint-specific. Either way it starts lower case, which the UI's auto-suggestion does not.

esc
↑↓ navigate · ↵ open · ⌘K anywhere