Appearance
Modeling Strategies
Central gives you four ways to model "this record is more complicated than one flat row": Extra Primary Keys, Built-In lists, Custom Lists, and Projections. Three of the four are chosen from the same control — the List Type selector on a Data Model's Lists tab — and the fourth lives one tab over.
They look similar from the outside and behave very differently downstream. This page is about picking the right one.
The whole decision in one question
Is it the same record, or a different record?
An Extra Primary Key gives you a second way to address the same record. Lists and Projections create additional records underneath it. Everything else follows from that.
Quick chooser
| You have… | Use | Where |
|---|---|---|
| One record the system stores in two tables, under two different ids | Extra Primary Key | Data Model → Extra Primary Keys tab |
| A child collection the common model already declares (an Order's Lines, an Item's Prices) | Built-In list | Lists tab → List Type = Built-In |
| A child collection the common model doesn't declare, and nothing else points at the children | Custom List | Lists tab → List Type = Custom List |
| A second level of one relationship that other records need to reference — and that some systems treat as the whole record | Projection | Lists tab → List Type = Projection |
Extra Primary Keys — one record, two identifiers
An Extra Primary Key is an additional identifier on the same record, in the same system. The record does not multiply. You are telling Central "this system also knows this record as X", so that data arriving under either identifier lands on the same entity.
The classic case is a system that replicates one thing into two tables — Locations that also appear in a Departments table, each with its own id. One Central record, two ways in.
Reach for one when all of these hold:
- It is genuinely the same business record — same name, same attributes, same lifecycle.
- The second identifier comes from the same source system.
- Nothing needs to reference the two identities differently. They are interchangeable.
If any of those breaks — especially the last — you want a Projection, not an extra key.
Extra keys don't split a record
If you find yourself wanting different attribute values, a different lifecycle, or different downstream routing for the "second identity", you are describing two records. Extra keys cannot express that, and forcing them to will produce one record whose values are whichever side wrote last.
See Data Models → Adding Extra Primary Keys for the mechanics. Extra keys also surface on referencing entities as Related Data.
Lists — Built-In vs Custom
Both kinds of list hold child records. The only difference is whether the common model already declares the relationship.
| Built-In | Custom List | |
|---|---|---|
| Declared by | The platform — Lines, Prices, Addresses, and so on | You — you type the list's name |
| Chosen via | The List Property dropdown, filtered to your entity type | A free-text List Name field |
| Child entity | The declared item entity type | ChildCustomEntity, shaped by a child Data Model |
| Child sub-type | Optional | Required — the platform errors without one |
Prefer Built-In whenever one fits. A declared list property is understood by the rest of the platform out of the box: the common model documents it, references to it resolve conventionally, and consumers know what an Order's Lines are without being told. A Custom List is a name you invented, so everything downstream has to be told about it.
Reach for a Custom List when the relationship you need genuinely isn't declared and you don't want to change the base entity to add it — professional certifications on a Contact, inspections on a Location, compliance records on a Product. You get a real, keyed child collection without a model change rippling through every consumer of that entity.
A Custom List name can't shadow a built-in one
If you type a name that matches a declared list property, Central rejects it and points you at the List Property dropdown. This is deliberate — two different mechanisms answering to the same name is the kind of ambiguity that only shows up in production.
Custom Lists covers the full setup; both kinds are populated the same way, via Looping Lists.
Projections — a second level that other records reference
Preview
Projections are in Preview alongside Custom Lists and are rolling out across environments. Your Central environment may not run them yet.
A Projection is a child list whose children represent a second level of one relationship — a location under a customer, a licence under an account, a property under a company. Mechanically it is a Custom List whose child Data Model carries the reserved sub-type ParentProjection. What makes it its own List Type is what the platform does with it afterwards.
The thing that makes a Projection necessary — and a Custom List insufficient — is this:
Different systems disagree about which level is "the record".
One system stores the account and its locations as two things. A second system's customers are the locations; it has no account at all. A third only has the account. All three are integrated against the same Central data, and a single order has to route correctly to all three.
That is what a Projection expresses. The base record and its projections are two levels of one relationship, and Central works out per system which level that system actually models, from the keys the projections carry. You do not configure that mapping; it is inferred from the data.
Setting one up
- On the parent Data Model, open the Lists tab and set List Type to Projection.
- Enter a List Name —
Locations,Licenses,Properties. This is how the list is addressed on the entity. - Choose the child Data Model. The picker offers only
ChildCustomEntitymodels carrying theParentProjectionsub-type; ➕ Add New Data Model… creates one with that sub-type already set. - On that child Data Model, set the Projection Key — the single property that identifies a projection within its parent. The picker appears at the top of the Data Model modal once the sub-type is
ParentProjection.
The projection key does not have to be globally unique
It only has to be unique within one parent. Two customers can both have a location called Main Warehouse; a reference always names the parent as well, so the search space is only ever that one parent's children. This is why a projection key can be a human label rather than an id.
ParentProjection is reserved
You cannot type it as a custom Sub Type on a Data Model. Create the list with List Type = Projection and let Central seed the sub-type — that path also wires the projection key and the child's key maps for you.
Referencing a projection
A record that points at a projection — an order pointing at the customer's location — needs two values to say what it means: which base record, and which projection within it. Central carries both on a single reference, which the map editor labels [Projection Reference] with base and projection badges on the two source columns.
It is an ordinary reference in every other respect. It resolves like one, indexes like one, and appears in the data model like one.
Authoring today
The map editor displays a projection reference but does not yet create one — the flag that marks the projection column is set through Code View. A visual-editor control is planned.
Custom List or Projection?
This is the choice most likely to go wrong, because a Projection is a Custom List underneath. The test is not what the children look like — it is what points at them.
| Ask | Custom List | Projection |
|---|---|---|
| Does anything outside the parent reference an individual child? | No | Yes — that is the whole point |
| Do connected systems disagree about whether the child or the parent is "the record"? | No | Yes |
| Is the child a real, independent thing in its own right? | Yes — a certification, an inspection | Not really — it is a re-slice of its parent |
| Does a child ever need to route a different record somewhere? | No | Yes |
A Contact's certifications are a Custom List: they travel with the contact and nothing addresses one on its own. A Customer's licences are a Projection: an order names one, and one downstream system thinks the licence is the customer.
When in doubt, start with the Custom List
It is the smaller commitment, and a list can be re-modelled as a Projection later. Going the other way is harder, because by then other records are referencing the children.
Worked comparison
One scenario — a customer that operates from several sales locations — modeled four ways, and what each gets you.
| Model | What Central holds | An order can say… | Works when |
|---|---|---|---|
| Extra Primary Key on the Customer | One customer, addressable by two ids | "customer 1001" (either id) | The two ids are the same customer and nothing distinguishes them — not this scenario |
| Built-In list | Not available — the common model does not declare sales locations on a Company | — | — |
Custom List Locations | One customer + N location children | "customer 1001" only | Locations are reference data you carry along, and nothing routes by them |
Projection Locations | One customer + N location children, each keyed per system | "customer 1001, location Loma Vista Sales" | A system models locations as its customers, or an order must route per location |
The first three all collapse the order onto the customer. Only the Projection preserves which location the order was for — and only the Projection lets one system receive the location while another receives the account, from the same single reference.
See Also
- Data Models — Properties, Extra Primary Keys, List Properties, Sub-Types
- Custom Lists — Setting up a free-form child collection
- Looping Lists — Populating any list: Loop All, Group by Field, Split by Separator
- Related Data — Carrying a referenced entity's values onto the referencing record
- Common Model Definitions — What the platform already declares