A customer has contacts. An order has line items. A project is assigned to several people, and each of those people is assigned to several projects. Business data is shaped by relationships, and a platform that pretends otherwise either pushes every implementer toward denormalization — stuffing repeated data into one wide record — or toward the familiar pain of hand-wiring two tables together and hoping the UI keeps up. First-class relationships are what separate a real data platform from a glorified spreadsheet.
Relationships on the platform come in the two shapes you'd expect. A one-to-many link — one Customer with many Contacts — shows up as a reference property on the "many" side (each Contact points to its Customer) and a reverse tab on the "one" side (each Customer page shows the list of its Contacts). A many-to-many link — say Project ↔ User — shows up as a multi-reference on both sides, with each side naturally offering the other as a related list. You describe the relationship once; both sides of the screen adapt.
Setting one up is about as simple as the description suggests. In the type editor, you add a reference property, pick the type it points to, choose single or multiple values, and optionally name the reverse side. That's the whole configuration. The moment you save, the forms gain the new field, the related-records tab appears automatically on the opposite type, search and filtering are aware of the link, and the API exposes it on both sides. No deployment, no migration scripts.
One small detail that makes a large difference day to day: reverse tabs are automatic. Open a Customer record and you'll see a tab for Contacts — not because someone remembered to configure it, but because the relationship itself implies it. Click through to see the list, sort it, filter it, add a new Contact prefilled with the parent Customer. This is the sort of connective tissue that would eat weeks of frontend work on a from-scratch build and arrives here as a consequence of declaring the link.
When order matters within a relationship — the line items on an invoice have to appear in the right sequence, the steps in a checklist mean something in context — the platform preserves a persistent order that users can drag to rearrange. When it doesn't matter, the default behavior stays out of the way. A type can also link to itself, which covers the familiar cases: parent tasks and subtasks, an organizational hierarchy of people, a thread of related incidents.
Filtering across relationships is where the payoff gets tangible. The query builder treats related-type properties as first-class citizens. You can ask the system for "invoices above five thousand where the customer's country is Germany" without writing any joins, because the builder walks the reference for you. The same goes for sorting and grouping. A view on Invoices can be organized by the Customer.Region field as easily as by a local one.
Permissions travel along these paths, too. The platform handles the subtle case — a user who can see the parent but not the child, or the reverse — by showing what they're allowed to see and quietly hiding the rest. The relationship doesn't become a backdoor into restricted data, and it doesn't confuse users with entries they can't open.
Relationships are one of those features that sounds procedural until you've worked in a tool that does them badly, at which point their absence is the first thing that pushes you toward the exit. We treat them as foundational, and the rest of the platform — queries, views, forms, API — leans on that foundation everywhere. The query builder article is the natural next step, since it's where the full power of having real relationships becomes visible.