Properties
A property is the listing itself: its title and description, what it costs (for sale, for rent, or both), its media, its lifecycle status, and the type-specific details that matter for its kind. A residential listing carries bedrooms and square footage; a commercial listing carries zoning and loading docks; land carries lot size and utilities. One model, three detail shapes.
Create a property
- TypeScript
- Python
import { PropertyType, PropertySubType, ListingType, ListingStatus, PropertyCondition } from 'wiil-js';
const property = await client.propertyConfig.create({
categoryId: 'cat_luxury',
addressId: 'addr_123',
title: 'Modern Downtown Condo',
description: 'Sleek 2BR condo with city skyline views',
propertyType: PropertyType.RESIDENTIAL,
propertySubType: PropertySubType.CONDO,
listingType: ListingType.SALE,
listingStatus: ListingStatus.ACTIVE,
salePrice: 750000,
salePriceCurrency: 'USD',
priceNegotiable: true,
features: {
bedrooms: 2,
bathrooms: 2,
parkingSpaces: 1,
squareFootage: 1200,
amenities: ['Gym', 'Pool', 'Concierge'],
utilities: ['Electric', 'Gas', 'Water'],
},
condition: PropertyCondition.NEW,
furnished: false,
images: ['https://example.com/living-room.jpg'],
isActive: true,
isFeatured: true,
});
from wiil.models.business_mgt import CreateProperty
prop = property_config.create(
CreateProperty(
category_id="cat_luxury",
address_id="addr_123",
title="Stunning Oceanfront Villa",
description="Luxury 5-bedroom villa with panoramic ocean views",
property_type="residential",
property_sub_type="villa",
listing_type="sale",
listing_status="active",
sale_price=2500000,
sale_price_currency="USD",
is_active=True,
)
)
For a rental, set listingType to rent, a rentalPrice, and a rentalPeriod (daily, weekly, monthly, yearly); for a listing that is both, set both with both prices.
Get, list, by category, search
- TypeScript
- Python
const property = await client.propertyConfig.get('prop_123');
const result = await client.propertyConfig.list({ page: 1, pageSize: 20, includeDeleted: false });
const inCategory = await client.propertyConfig.getByCategory('cat_luxury', { page: 1, pageSize: 20 });
const found = await client.propertyConfig.search('oceanfront villa', { page: 1, pageSize: 10 });
from wiil.types import PaginationRequest
loaded = property_config.get("prop_123")
all_properties = property_config.list(PaginationRequest(page=1, page_size=20))
category_properties = property_config.get_by_category("cat_luxury", PaginationRequest(page=1, page_size=20))
search_results = property_config.search("office", PaginationRequest(page=1, page_size=20))
Get by address
Looking a property up by its address is exposed through the TypeScript SDK.
const property = await client.propertyConfig.getByAddress('addr_123');
Update and delete
Update a property to change pricing, move its listingStatus through the sales cycle, or take it off the market.
- TypeScript
- Python
import { ListingStatus } from 'wiil-js';
const updated = await client.propertyConfig.update({
id: 'prop_123',
salePrice: 725000,
listingStatus: ListingStatus.PENDING,
priceNegotiable: false,
});
await client.propertyConfig.delete('prop_123');
from wiil.models.business_mgt import UpdateProperty
updated = property_config.update(
UpdateProperty(id="prop_123", listing_status="under_offer", is_featured=True)
)
property_config.delete("prop_123")
Batch create
- TypeScript
- Python
import { PropertyType, PropertySubType, ListingType } from 'wiil-js';
const properties = await client.propertyConfig.createBatch([
{
categoryId: 'cat_luxury',
addressId: 'addr_001',
title: 'Oceanfront Villa',
propertyType: PropertyType.RESIDENTIAL,
propertySubType: PropertySubType.VILLA,
listingType: ListingType.SALE,
salePrice: 2500000,
features: { bedrooms: 5, bathrooms: 4, squareFootage: 4500 },
isActive: true,
},
]);
from wiil.models.business_mgt import CreateProperty
properties = property_config.create_batch([
CreateProperty(title="Downtown Loft", description="Modern 2BR loft", category_id="cat_apartments", address_id="addr_nyc", property_type="residential", listing_type="rent", rental_price=2500, rental_period="monthly"),
CreateProperty(title="Beach House", description="3BR oceanfront", category_id="cat_houses", address_id="addr_miami", property_type="residential", listing_type="sale", sale_price=750000, sale_price_currency="USD"),
])
Both SDKs cap batch creation at 50 properties per request.
Property fields
| Field | Type | Required | Description |
|---|---|---|---|
id | string | auto | Unique identifier |
categoryId | string | Yes | Category the property belongs to |
addressId | string | Yes | The property's address |
title | string | Yes | Listing title |
description | string | null | No | Detailed description |
propertyType | enum | Yes | residential, commercial, land |
propertySubType | enum | Yes | house, condo, office, lot, … |
listingType | enum | Yes | sale, rent, or both |
listingStatus | enum | Yes | Lifecycle status (default DRAFT) |
salePrice / salePriceCurrency | — | No / Yes | Sale price and currency (default USD) |
rentalPrice / rentalPeriod / rentalPriceCurrency | — | No | Rental price, period, currency |
priceNegotiable | boolean | Yes | Whether price is negotiable (default false) |
features | object | null | No | parkingSpaces, amenities, utilities |
condition | enum | null | No | new, excellent, good, fair, needs_work, fixer_upper |
furnished | boolean | Yes | Whether furnished (default false) |
images | array | Yes | Image URLs (default []) |
virtualTourUrl / videoUrl | string | null | No | Media links |
availableFrom / availableTo | number | null | No | Availability window (rentals) |
isActive / isFeatured / isVerified | boolean | Yes | Listing flags |
mlsNumber / externalId | string | null | No | MLS and external references |
residentialDetails / commercialDetails / landDetails | object | null | No | Type-specific details (below) |
Enums
| Enum | Values |
|---|---|
PropertyType | residential, commercial, land |
PropertySubType | house, apartment, condo, townhouse, villa, office, retail, warehouse, industrial, lot, farm, acreage |
ListingType | sale, rent, both |
ListingStatus | DRAFT, ACTIVE, PENDING, SOLD, LEASED, OFF_MARKET, EXPIRED |
RentalPeriod | daily, weekly, monthly, yearly |
PropertyCondition | new, excellent, good, fair, needs_work, fixer_upper |
Type-specific details
Populate the block that matches the propertyType.
ResidentialDetails
bedrooms, bathrooms, and squareFootage are required; optional fields include halfBaths, lotSize/lotSizeUnit, yearBuilt, floors, basementType, atticFinished, heatingType, coolingType, roofType, exteriorMaterial, garageSpaces, hasPool, and hasFireplace.
CommercialDetails
squareFootage and zoningType are required; optional fields include usableSquareFootage, floors, ceilingHeight, loadingDocks, driveInDoors, freightElevator, passengerElevator, yearBuilt, previousUse, buildOutStatus (shell/partial/turnkey), hvacType, powerCapacity, and sprinklerSystem.
LandDetails
lotSize, lotSizeUnit, zoning, and utilitiesAvailable are required; optional fields include topography, roadFrontage, roadAccess, waterSource, sewerType, soilType, floodZone, floodZoneDesignation, easements, surveyAvailable, mineralRights, and timberValue.
Query options
Property queries filter by search, categoryId, addressIds, address, propertyType, propertySubType, listingType, listingStatus[], isActive, isFeatured, isVerified, condition, furnished, priceRange, bedroomsRange, bathroomsRange, and squareFootageRange, sorted by title, salePrice, rentalPrice, createdAt, displayOrder, or squareFootage (asc / desc).
Match propertySubType to propertyType (a warehouse is commercial, not residential), populate the matching details block, and keep listingStatus current through the sales cycle so search and pipeline stay accurate.