API Usage Guide¶
This guide covers programmatic usage of PyPropertyMe for accessing the PropertyMe API.
Client Overview¶
The Client class provides a clean interface to all PropertyMe API endpoints.
from pypropertyme.client import Client
# Create client with OAuth token
client = Client.get_client(token)
# Access entity clients
contacts = await client.contacts.all()
properties = await client.properties.all()
Basic Usage¶
Fetching All Entities¶
Every entity client supports the .all() method to fetch all records:
# Fetch all contacts
contacts = await client.contacts.all()
# Fetch all properties
properties = await client.properties.all()
# Fetch all tenancies
tenancies = await client.tenancies.all()
# Fetch all tenancy balances
balances = await client.tenancy_balances.all()
# Fetch all members
members = await client.members.all()
# Fetch all tasks
tasks = await client.tasks.all()
# Fetch all inspections
inspections = await client.inspections.all()
# Fetch all jobs
jobs = await client.jobs.all()
Fetching by ID¶
Most entity clients support fetching a single record with full details:
# Get contact with full details
contact = await client.contacts.get("contact-id")
# Returns ContactDetail with nested contact data
# Get property with full details
property = await client.properties.get("property-id")
# Returns PropertyDetail with ownership, tenancy, listings
# Get task
task = await client.tasks.get("task-id")
# Get job
job = await client.jobs.get("job-id")
# Get inspection with full report
inspection = await client.inspections.get("inspection-id")
# Returns InspectionDetail with embedded property, tenant, owner, report
# Get tenancy balance by tenancy ID
balance = await client.tenancy_balances.get("tenancy-id")
API Limitations
members and tenancies do not support fetching by ID due to PropertyMe API limitations.
Property Endpoints¶
Properties have additional filtered endpoints with pagination support:
# All properties (no pagination)
all_properties = await client.properties.all()
# Filtered endpoints (with pagination)
sales = await client.sales_properties.all()
rentals = await client.rental_properties.all()
archived = await client.archived_properties.all()
vacant = await client.vacant_properties.all()
Tenancy Endpoints¶
# All tenancies
tenancies = await client.tenancies.all()
# Tenancy financial balances
balances = await client.tenancy_balances.all()
Model Types¶
PyPropertyMe uses Pydantic models for type safety. Each entity has a list model and (usually) a detail model:
| Entity | List Model | Detail Model |
|---|---|---|
| Contact | Contact |
ContactDetail |
| Property | Property |
PropertyDetail |
| Tenancy | Tenancy |
- |
| TenancyBalance | TenancyBalance |
TenancyBalance |
| Member | Member |
- |
| Task | Task |
- |
| Inspection | Inspection |
InspectionDetail |
| Job | Job |
- |
Working with Models¶
# Models are Pydantic BaseModel instances
contact = contacts[0]
# Access attributes directly
print(contact.name_text)
print(contact.email)
print(contact.is_owner)
# Serialize to dict
contact_dict = contact.model_dump()
# Serialize to JSON
contact_json = contact.model_dump_json()
Detail Models¶
Detail models often have nested structures:
# ContactDetail has nested contact object
contact_detail = await client.contacts.get("contact-id")
print(contact_detail.contact.name_text)
print(contact_detail.contact.roles)
print(contact_detail.folio_id)
# PropertyDetail has ownership and tenancy info
property_detail = await client.properties.get("property-id")
print(property_detail.ownership)
print(property_detail.tenancy)
# InspectionDetail has embedded related entities
inspection_detail = await client.inspections.get("inspection-id")
print(inspection_detail.property)
print(inspection_detail.tenant)
print(inspection_detail.owner)
print(inspection_detail.inspection_report)
Pagination¶
The .all() method automatically handles pagination for endpoints that support it:
# Automatically fetches all pages
rentals = await client.rental_properties.all()
For manual control over pagination, use the iterator:
# Use get_iter() for paginated endpoints
async for property in client.rental_properties.get_iter():
print(property.reference)
Pagination Support
Not all endpoints support pagination. The main properties endpoint does NOT support pagination; use the filtered endpoints (rental_properties, sales_properties, etc.) for pagination.
Complete Example¶
import asyncio
import json
from pathlib import Path
from pypropertyme.client import Client
async def main():
# Load tokens from CLI authentication
token_path = Path.home() / ".pypropertyme" / "tokens.json"
token = json.loads(token_path.read_text())
# Create client
client = Client.get_client(token)
# Fetch all properties
properties = await client.properties.all()
print(f"Found {len(properties)} properties")
# Get details for first property
if properties:
detail = await client.properties.get(properties[0].id)
print(f"Property: {detail.address.full_address}")
if detail.ownership:
print(f"Owner: {detail.ownership}")
if detail.tenancy:
print(f"Tenancy: {detail.tenancy}")
asyncio.run(main())
Next Steps¶
- API Reference - Auto-generated API documentation
- Entity Relationships - How entities relate to each other
- Authentication - OAuth flow details