Common Data Model
Every PropTech system models the world a little differently. The Common Data Model is the single normalized shape PropSocket maps them all into, so you write deserialization once instead of once per vendor. The MVP exposes four entities — Property, Unit,Resident, and Lease — plus the LeaseResidentrelation that ties residents to leases.
How they relate
The hierarchy is small and predictable:
- A Property has many Units and many Leases.
- A Lease belongs to exactly one Unit and one Property.
- A Lease and a Resident have a many-to-many relationship — a lease can have several residents (primary, co-resident, guarantor), and a resident can hold several leases over time. LeaseResident is that join.
Conventions every entity follows
These hold across all four entities. Learn them once:
- IDs. Every record has a PropSocket-minted
id(the canonical identifier you use in/v1/{entity}/{id}calls) and anx_id— the native identifier from the source integration. It'sx_id, neversource_id. - Money. Always an object:
{ "amount": 285000, "currency": "USD" }.amountis an integer in minor units —285000is $2,850.00. No floats, no rounding drift. - Datetimes & dates. Datetimes are UTC ISO 8601 (
2026-05-11T18:04:58Z). Date-only fields areYYYY-MM-DD. - Enums. Lowercase
snake_casestrings (active,month_to_month). Code defensively — tolerate enum values you don't recognize, as we add new ones additively. - Soft deletion. Records are never physically deleted. A removed record gets a non-null
deleted_attimestamp. List endpoints exclude soft-deleted records by default; pass?include_deleted=trueto see them. - custom_data. A free-form JSON object on every entity for integration-specific fields the CDM doesn't standardize. Defaults to
{}. - Freshness. Every record carries
ps_synced_at— the UTC timestamp of the last successful sync that covered it, even when nothing changed (distinct fromupdated_at). It's PropSocket operational metadata in the reservedps_namespace. See Conventions.
Property
A physical asset — a building, community, complex, or standalone home. The top of the hierarchy; everything location-bound references a Property.
| Field | Type | Notes |
|---|---|---|
| name | string | Display name. |
| type | enum | apartment, condo, single_family, … |
| status | enum | active, inactive, lease_up, … |
| address | Address | Structured object. |
| total_units | integer | Rentable units. |
{
"id": "prp_01HX0G5T8N3KEWBYV2QMR4DCFA",
"x_id": "entrata-property-3391",
"integration_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Maple Court Apartments",
"type": "apartment",
"status": "active",
"address": {
"line_1": "1400 Maple Court",
"line_2": null,
"city": "Austin",
"state": "TX",
"postal_code": "78704",
"country": "US"
},
"year_built": 2014,
"total_units": 188,
"total_buildings": 6,
"phones": [
{ "type": "work", "number": "+15125550133", "primary": true }
],
"custom_data": {},
"created_at": "2026-05-01T09:12:44Z",
"updated_at": "2026-05-11T18:04:58Z",
"deleted_at": null,
"ps_synced_at": "2026-05-11T18:04:58Z"
}Unit
An individual rentable space within a Property — an apartment, a suite, a single-family home.
| Field | Type | Notes |
|---|---|---|
| property_id | UUID | Parent Property. |
| unit_number | string | e.g. "204". |
| status | enum | occupied, vacant, notice, … |
| bedrooms / bathrooms | number | Decimals allowed (studios, half-baths). |
| market_rent | Money | Integer minor units + currency. |
{
"id": "unt_01HX1H6U9P4LFXCZW3RNS5EDGB",
"x_id": "entrata-unit-55812",
"integration_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"property_id": "prp_01HX0G5T8N3KEWBYV2QMR4DCFA",
"unit_number": "204",
"type": "apartment",
"status": "occupied",
"floor": "2",
"building": "C",
"bedrooms": 2,
"bathrooms": 1.5,
"square_feet": 980,
"market_rent": { "amount": 285000, "currency": "USD" },
"floor_plan_name": "The Aspen 2BR",
"custom_data": {},
"created_at": "2026-05-01T09:13:02Z",
"updated_at": "2026-05-11T18:04:58Z",
"deleted_at": null,
"ps_synced_at": "2026-05-11T18:04:58Z"
}Resident
A person who is a current or past tenant. Carries contact and demographic detail.
| Field | Type | Notes |
|---|---|---|
| first_name / last_name | string | Required. |
| status | enum | current, past, future, applicant, … |
| emails / phones | array | Email and Phone objects. |
| lease_ids | UUID[] | Leases this resident is on. |
| balance | Money | Outstanding balance. |
{
"id": "res_01HX2J7V0Q5MGYDAW4SOT6FEHC",
"x_id": "entrata-resident-44218",
"integration_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"property_id": "prp_01HX0G5T8N3KEWBYV2QMR4DCFA",
"first_name": "Dana",
"last_name": "Okonkwo",
"display_name": "Dana Okonkwo",
"status": "current",
"type": "primary",
"emails": [
{ "type": "personal", "address": "dana.o@example.com", "primary": true }
],
"phones": [
{ "type": "mobile", "number": "+14155550118", "primary": true }
],
"move_in_date": "2026-06-01",
"lease_ids": ["lse_01HX9P3K2N7QZRWY4B8MJ5VCDF"],
"balance": { "amount": 0, "currency": "USD" },
"custom_data": {},
"created_at": "2026-05-01T09:14:20Z",
"updated_at": "2026-05-11T18:04:58Z",
"deleted_at": null,
"ps_synced_at": "2026-05-11T18:04:58Z"
}Lease
The rental agreement linking residents to a unit at a property. The core transactional entity — and the one that exposes the LeaseResident relation.
| Field | Type | Notes |
|---|---|---|
| property_id / unit_id | UUID | The unit being leased. |
| resident_ids | UUID[] | At least one. The residents on the lease. |
| status | enum | pending, active, renewed, expired, terminated, … |
| start_date / end_date | date | end_date is null for month-to-month. |
| rent_amount | Money | Monthly rent. |
| residents | LeaseResident[] | Nested relation — see below. |
{
"id": "lse_01HX9P3K2N7QZRWY4B8MJ5VCDF",
"x_id": "entrata-lease-8847291",
"integration_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"property_id": "prp_01HX0G5T8N3KEWBYV2QMR4DCFA",
"unit_id": "unt_01HX1H6U9P4LFXCZW3RNS5EDGB",
"resident_ids": ["res_01HX2J7V0Q5MGYDAW4SOT6FEHC"],
"status": "active",
"type": "fixed",
"start_date": "2026-06-01",
"end_date": "2027-05-31",
"term_months": 12,
"rent_amount": { "amount": 272500, "currency": "USD" },
"security_deposit": { "amount": 285000, "currency": "USD" },
"balance": { "amount": 0, "currency": "USD" },
"signed_date": "2026-05-11",
"is_renewal": false,
"residents": [
{
"resident_id": "res_01HX2J7V0Q5MGYDAW4SOT6FEHC",
"x_id": "entrata-resident-44218",
"role": "primary"
}
],
"custom_data": {},
"created_at": "2026-05-11T17:41:52Z",
"updated_at": "2026-05-11T17:41:52Z",
"deleted_at": null,
"ps_synced_at": "2026-05-11T18:04:58Z"
}LeaseResident (relation only)
LeaseResident is the join between a Lease and a Resident — it carries therole a resident plays on a specific lease (primary,responsible, occupant, …). role is the source PMS's relationship label, normalized to lowercase snake_case — an open set, not a fixed enum. It is not a first-class endpoint: there is no /v1/lease-residents collection and no standalone record to fetch. You read it as the nested residents array on a Lease, shown above:
"residents": [
{
"resident_id": "res_01HX2J7V0Q5MGYDAW4SOT6FEHC",
"x_id": "entrata-resident-44218",
"role": "primary"
}
]To go the other direction — every lease a resident is on — read the resident'slease_ids array, or filter leases with?resident_id={id}. See filtering.
Soft-deleted records
When a record disappears from the source integration, the next sync sets its deleted_atrather than removing the row. List endpoints hide these by default. Request them with?include_deleted=true and check the deleted_at field:
{
"id": "unt_01HX1H6U9P4LFXCZW3RNS5EDGB",
"x_id": "entrata-unit-55812",
"status": "down",
"deleted_at": "2026-05-12T03:22:10Z",
"updated_at": "2026-05-12T03:22:10Z",
"ps_synced_at": "2026-05-12T03:22:10Z"
}Next
See these shapes served live in the API reference, learn how the cache stays in sync in the architecture overview, or start reading in the quickstart.