Skip to main content
Version: v0.25.0 (Latest)

Persons and Organizations

This page covers the party types you work with most, the data that hangs off them, the way you extend them with your own properties, and how that data becomes the basis for role- and attribute-based authorization. It assumes you have read The Party Model for the "everything is a party" framing. Organization units carry enough weight to have their own page, Organization Units.

The Typed Party Types

Every party shares the same base contract: an identifier, the tenant it belongs to, a display name, an origin that records whether it was created here or synced from outside, the single home organization unit it lives in, the specializations it bears, its addresses, and the standard audit fields. On top of that contract each type adds the fields that only make sense for it.

TypepartyTypeWhat it addsTypical use
Personnatural_personfirst, middle, last name; birth datea human individual
Organizationorganizationlegal name, organization type, industry, contact email, website, privacy and terms URIsa company, institution, or legal entity
Organization Unitorganization_unitparent unit, name, terms URI, branding, inheritance policydepartments, faculties, locations, workspaces
Serviceserviceservice type, endpoint URI, OAuth client idapplications, endpoints, integrations, agents
Groupgroupname, membersaddressing and authorization sets

Each type has its own REST resource (/persons, /organizations, and so on) that returns the typed object directly, and there is a polymorphic /parties view for when you do not know a party's type in advance. Both are covered on the REST API page.

Persons

A person is the human in your model. Beyond the shared base it carries the name parts and a birth date, and it is the type that most often becomes a login identity. It does not have to, though: a person can exist purely as a contact or as the endpoint of a relationship, with no ability to authenticate anywhere. That separation between being known and being able to log in is the subject of Identities and Identifiers.

Organizations

An organization is a legal entity. Alongside its registered legal name it carries the operational details you advertise about it, including a contact email, a website, a privacy policy, and terms of service. Organizations are full participants rather than lookup rows: they hold relationships, own other parties, act as a customer in one context and a supplier in another, and can themselves be the subject of credentials.

Organizations also carry their formal registrations, the registered numbers that prove an entity is who it claims to be. A VAT number, a Legal Entity Identifier, a DUNS number, or a Chamber of Commerce entry each lives as a registration attached to the organization, with the issuing scheme recorded alongside the value. Because registrations are first-class records rather than free-text fields, you can list them, add new ones as an entity is verified in more jurisdictions, and reason about which schemes an organization has been registered under. They are managed through the organization's registrations sub-resource on the REST API.

Services and Groups

A service is a software-backed participant: an integration, an endpoint, an automated actor, or an application. A service that people sign in to additionally carries a login configuration, which is what makes it a login surface, covered under Identities and Identifiers. The same service party is the natural home for the future agent type, so an MCP endpoint or an autonomous worker is modelled the same way as any other service, with its own identifiers and its own bindings.

A group is the simplest type: a named set of members, with no specializations or attributes of its own. Because a group is itself owned by an organization unit and can gather any mix of party types, including persons and organizations in the same group, it is covered in depth alongside units in Organization Units.

Contact Points: Addresses

Any party can carry electronic and physical addresses, and they are modelled as records attached to the party rather than as fields baked into each type. An electronic address holds something like an email address, a phone number, or a messaging handle together with its kind, while a physical address holds the postal detail. Keeping addresses separate from the typed body means a person and an organization attach addresses the same way, a party can hold several of each, and the set can grow or change without touching the party itself.

Addresses are hydrated on demand rather than returned on every read. When you fetch a party you can ask for its addresses to be included; when you do not, the address fields come back empty, which keeps ordinary reads small. The address sub-resources on the REST API cover listing, adding, updating, and removing them.

Extending a Party With Your Own Properties

Out of the box a party carries only the fields above. Your world has more, such as a student number, an employee's cost centre, or a supplier's onboarding tier. You add these through specializations.

A specialization is a role a party plays, named by a subtype label such as employee, customer, supplier, or student. On its own a subtype is just a label you can declare and filter on. When you bind it to a semantic profile it gains a validated set of attributes: the profile defines which fields exist, their types, and their constraints, and the values you store are checked against the exact profile version they were captured under.

// A person bearing one typed specialization
{
"partyType": "natural_person",
"displayName": "Lena Vos",
"firstName": "Lena", "lastName": "Vos",
"specializations": [
{
"subtype": "student",
"profileId": "student",
"profileVersion": "2",
"attributes": { "studentNumber": "S1029384", "faculty": "Law", "enrolmentYear": 2024 }
}
]
}

A few rules keep this safe to depend on. A bare subtype with no attributes is always allowed and needs no license; the role label is recorded either way. Storing validated attributes is the part that requires the semantic license; without it, an attempt to store attributes is rejected rather than quietly kept in an ungoverned bag. The profile is the schema. There is no second schema to author or host: the bound profile decides which fields a role may carry and which are required, so a value for a field the profile does not define is rejected, and a required field that is missing is rejected. The profile identifier and version are stored with the values, so the data stays reproducible against the exact profile it was validated against, and a newer profile version never silently re-validates older data. Attributes are namespaced per specialization rather than flattened into one object, so several roles can carry overlapping field names without colliding, and reading the party back returns each role's values grouped under that role. This is how a party is extended with your own properties: you define a profile for the role, bind the subtype to it, and the party carries validated values for that role from then on.

Multi-Typing: One Record, Several Hats

The base contract holds a list of specializations, so a single party can play several roles at once. A person can be both an employee and a customer; an organization can be both a customer and a supplier. Each role binds to a distinct profile and carries its own attribute set, all on one party and one identity.

Modelling one person as several roles: either multiple specializations on one party, or separate parties linked by a same-entity relationship

Each role can also live in its own part of the organization. A specialization can name the organization unit that role belongs to, separate from the party's own home unit, so a person who is a student in the Faculty of Law and an employee in IT Services is one party whose two roles sit in two different units. The party keeps a single home unit, and each role can sit where it belongs without forcing you to split the record.

There is one invariant worth holding onto: a party may bear at most one specialization per profile. You cannot pin the same profile twice on one party, because that would be two personas rather than two roles. When you genuinely need the same role held twice, attribute sets that should not share a record, or separate login identities, you model them as separate parties linked by a same_entity relationship instead, which is covered under Relationships.

The student-and-staff example shows both choices. When it is one record, Lena is one person who is both a student and a staff member, with one identity, two validated attribute sets side by side, and each role placed in its own unit if the two belong in different parts of the school. You keep them as two parties only when the personas need separate login identities, or attribute sets that should not share a record, and then a governed and auditable same_entity link ties them back together. Choosing between them is a modelling decision rather than a system limitation, and a tenant can use both at once.

Roles and Attributes Drive RBAC and ABAC

The roles and attributes a party carries are exactly what role- and attribute-based authorization need. Role-based access keys on the label, so a party whose specializations include staff can be granted the staff permission set, and because roles are a list a party can hold several such grants at once. Attribute-based access keys on the validated values, so a rule such as "faculty equals Law" or "onboarding tier is at least gold" reads the attributes on the relevant specialization and decides from them.

Both of these answer questions about a single party from its own data. Questions that follow the graph from one party to another, such as whether someone is the manager of a resource's owner, are relationship-based, and those are the subject of the next page. The engine that evaluates these rules is the authorization layer; the party model is where the roles and attributes it reads come from.