Filtering & sorting

Every list endpoint accepts filters as query parameters and a single order-by. The tables below list exactly what each entity supports — reach for a parameter that isn't here and you'll get a 422 naming the valid options. Filters narrow server-side, so you never download rows you'll discard. Pair this with Paginationfor stable, complete reads.

Property

FilterMatchNotes
statusexactsnake_case enum value
typeexactsnake_case enum value
namecontainscase-insensitive substring
x_idexactthe native PMS identifier
integration_idexactscope to one connected source

To fetch a single property by its PropSocket id, use GET /v1/properties/{id} — there's no id filter on the list endpoint.

Unit

FilterMatchNotes
property_idexactunits within one property
statusexact
typeexact
unit_numberexact
buildingexact
bedrooms_gte / bedrooms_lterangeinclusive bounds
bathrooms_gte / bathrooms_lterangeinclusive bounds
x_idexact

Resident

FilterMatchNotes
property_idexactresidents on a lease at this property
lease_idexactresidents on a specific lease
statusexact
typeexact
first_namecontainscase-insensitive substring
last_namecontainscase-insensitive substring
x_idexact

property_id and lease_id traverse the lease-resident relationship, so a resident on more than one matching lease is returned once, not duplicated.

Lease

FilterMatchNotes
property_idexact
unit_idexact
resident_idexactleases a resident is on
statusexact
typeexact
start_date_gte / start_date_lterangeYYYY-MM-DD, inclusive
end_date_gte / end_date_lterangeYYYY-MM-DD, inclusive
x_idexact

A lease's residents are nested in the response as a relation array — LeaseResident is relation-only, with no top-level collection of its own.

Combinator semantics

Different filters combine with AND — every parameter you add narrows the result further. There is no nesting and no NOT in the current version.

AND across parameters
# Different filters combine with AND. This returns active apartments in one property.
curl "https://api.propsocket.io/v1/units?property_id=prp_01HX0G5T8N3KEWBYV2QMR4DCFA&status=active&type=apartment" \
  -H "Authorization: Bearer ps_test_YOUR_TEST_KEY"

For OR within a single field, pass a comma-separated list — the filter matches any value in it. There is no OR across different fields; for that, make separate requests and union the results yourself.

Multi-value — OR within one field
# A single filter accepts a comma-separated list — matches ANY value (OR within the field).
# "active OR pending" units:
curl "https://api.propsocket.io/v1/units?status=active,pending" \
  -H "Authorization: Bearer ps_test_YOUR_TEST_KEY"

Range filters

Numeric and date ranges use _gte / _lte pairs (greater-than-or-equal, less-than-or-equal). Send one or both bounds.

Range pair
# Range filters use _gte / _lte pairs. Two- and three-bedroom units:
curl "https://api.propsocket.io/v1/units?bedrooms_gte=2&bedrooms_lte=3" \
  -H "Authorization: Bearer ps_test_YOUR_TEST_KEY"

Time-window filters

Every entity supports time-window filters on its system timestamps:updated_after, created_after, and created_before, each taking a UTC ISO 8601 value. These are the backbone of incremental sweeps — pull only what changed since your last watermark instead of re-reading the whole collection. Pairupdated_after with order-by=updated_at:asc for a stable, resumable walk.

Time window
# Time-window filters on every entity, by created_at / updated_at.
# Everything changed since your last sweep:
curl "https://api.propsocket.io/v1/leases?updated_after=2026-05-20T00:00:00Z&order-by=updated_at:asc" \
  -H "Authorization: Bearer ps_test_YOUR_TEST_KEY"

Sorting

Sort with a single order-by=field:asc|desc. The default iscreated_at:desc. For stable, resumable pagination, sort by created_at:ascso newly inserted rows append to the end of the sequence rather than shifting earlier pages.

order-by
# order-by is field:asc|desc. Default is created_at:desc.
curl "https://api.propsocket.io/v1/leases?order-by=start_date:asc" \
  -H "Authorization: Bearer ps_test_YOUR_TEST_KEY"

Each entity sorts on a defined set of fields. Ask for a field an entity doesn't expose and you'll get a 422 listing the valid ones — see Errors.

Soft-deleted records

List and retrieve endpoints exclude soft-deleted records by default. To include them — to reconcile removals or audit deletions — add ?include_deleted=true and read each record's deleted_at.

Next

Filters compose with paging — see Pagination for the envelope and the loop, and the nightly units CSV recipe for filtering and paging together in one job.