Entity Types
An entity type says what role a model plays in your data model — whether it describes the people you build audiences about, something related to them, or things that happen to them. Classifying a model is what makes it usable in the audience builder, in relationships and in identity resolution.
The Three Entity Types
A model carries exactly one entity type. It is a property of the model, not a separate object you create.
| Entity type | What it describes | Example |
|---|---|---|
| Parent | The subject you build audiences about — one row per person or account | customers, users |
| Related | Attributes belonging to a parent record, reached through a relationship | subscriptions, addresses |
| Event | Things that happened, with a timestamp — many rows per parent | orders, page_views |
A model you have not classified yet shows as Unclassified on the Relationships page, with a note that it needs an entity type before the audience builder can use it.
Choosing between Related and Event comes down to whether the rows are a timeline. If each row is a thing that happened at a moment and you would ever filter on when, it is an event. If the rows simply describe the parent, it is related.
Classifying a Model
Using the UI
- Navigate to Relationships in the left sidebar
- Find the model under Models and click its row, or use the Configure button
- Choose the entity type — Parent, Related or Event
- Set the primary key column that identifies each record
- For an event model, set the timestamp column that orders the rows
- Mark which columns are identifiers, and any per-column settings
- Click Save
Using the API
An entity type is a property of a model rather than a resource of its own, so you assign one through the model’s entity configuration. entity_type is one of parent, related or event. column_config is an array, one entry per column, carrying that column’s display alias, whether it is offered in the audience builder, its data type, and its sensitivity:
curl -X PUT "$API_BASE_URL/api/v1/workspaces/$WORKSPACE_ID/models/$MODEL_ID/entity-config" \
-H "Authorization: Bearer $API_TOKEN" \
-H "X-Workspace-ID: $WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{
"entity_type": "parent",
"primary_key_column": "customer_id",
"timestamp_column": "updated_at",
"column_config": [
{ "name": "customer_id", "alias": "Customer ID", "enabled": true, "data_type": "string" },
{ "name": "email", "alias": "Email", "enabled": true, "data_type": "string", "sensitivity": "redacted", "pii_type": "email" },
{ "name": "plan", "alias": "Plan", "enabled": true, "data_type": "string" },
{ "name": "updated_at", "alias": "Updated at", "enabled": true, "data_type": "timestamp" }
]
}'The response is the updated model. See Base URL for your instance’s API base URL and Authentication for the required headers.
Column Configuration
An entity type has no attribute list of its own — its columns are the model’s columns. What the entity configuration page adds is per-column settings that decide how each one behaves downstream.
| Setting | What it does |
|---|---|
| Enabled | Whether the column is offered in the audience builder at all. Turn off the columns nobody filters on and the picker stays readable. |
| Column Name | The column as it exists in the model. Not editable here — it comes from the model. |
| Data Type | The type Zeotap reasons about, which decides which operators the filter builder offers |
| Alias | A display name for the column. Blank falls back to the column name. |
| Sensitivity | How the column’s values are protected — see below |
| PII Type | What kind of personal data the column holds (email, phone, name, address, ssn, dob, custom). Used to hash values on the way to a destination that expects hashed identifiers. |
Sensitivity
| Level | Effect |
|---|---|
| (none) | No restriction |
| Redacted | Values are masked in previews and value suggestions. The column is still syncable. |
| Sync Only | Hidden from the UI entirely, but still deliverable to a destination |
| Blocked | Hidden from the UI and excluded from field mappings — it cannot leave the warehouse |
Zeotap detects likely PII from column names when a model is first classified and seeds a sensitivity for those columns, so an email column arrives redacted rather than waiting for someone to notice. See PII Masking.
Primary Key and Timestamp
Every classified model names a primary key column — the column that identifies a record, and the key relationships join on.
An event model also names a timestamp column. It is what orders the rows and what a time-window filter (“in the last 30 days”) is evaluated against, so an event model without one cannot answer a question about when.
A parent or related model may name one too, and there it is optional. Setting it does one thing and one thing only: it lets the model rank its own rows. That is what
- golden-record Most Recent survivorship needs to pick the newest value for an attribute sourced from this model — without it the strategy is blocked, because every row would tie and the winner would fall through to the primary key;
- latest/earliest row selection needs when a sync maps a column through a relationship into this model.
It changes nothing else. A related model with a timestamp column is still a related model: no event-style time window appears in the audience builder, no Customer 360 card starts hiding older rows, and nothing about how it joins changes.
If the model sits on a table a loader landed and the source has no timestamp of its own, use the platform’s own stamp: _ss_loaded_at on a pull loader’s table, or received_at on a push loader’s. Either one holds the moment Zeotap received the row; _ss_loaded_at appears in the picker as ingestion time. See Reserved columns.
Reclassifying a Model
Change a model’s entity type the same way you set it: open it under Relationships and save a different one.
Because relationships, audiences and identity graphs are all built on top of the classification, changing it can invalidate them — a relationship pointing at a model that is no longer a parent, or an audience filtering on a column that is no longer offered. Check what depends on the model before you change its role.
Deleting a model that a relationship depends on is refused outright: the error names the relationship, and the model becomes deletable once that relationship is gone.
Next Steps
- Define relationships between your classified models
- Visualize your data model with the ERD viewer
- Set up identity resolution using the identifier columns you configured