Skip to contentSkip to Content
API ReferenceProperties

Properties API

CRUD endpoints for managing your property listings programmatically.

For image uploads, see Property Images.

Free Trial scope

The Free Trial API supports private, image-free property CRUD. Trial creates are always private. Trial updates and deletes reject records that are already public or have images, so the safe trial path cannot publish listings or orphan stored media. Property image endpoints, imageUrls imports, bulk operations, and other provider, AI, or outbound actions are not available during the trial. Trial property mutations do not trigger geocoding or outbound webhook/notification side effects.

List Properties

GET /api/v1/properties

Returns a paginated list of your non-deleted properties.

Query parameters:

ParameterTypeDescription
pageintegerPage number (default 1).
limitintegerItems per page (default 20, max 100; Free Trial max 20).
minRentnumberMinimum monthly rent (USD).
maxRentnumberMaximum monthly rent (USD).
minBedroomsintegerMinimum bedrooms. 0 is a lower bound, not an exact Studio filter.
bedroomTypestudioMatch exactly zero bedrooms. This is separate from property type.
propertyTyperepeated stringDevelopment preview: house, apartment, condo, townhouse, or room. Repeat to match any selected type.
minBathroomsnumberMinimum bathrooms (allows 1.5 etc).
availableBeforestringISO date YYYY-MM-DD — only properties available on or before this date.
petFriendlytrue|falseFilter pet-friendly properties.
hasParkingtrue|falseFilter properties with parking.
citystringSubstring match on city.

Response (200 OK):

{ "data": [ { "id": "550e8400-e29b-41d4-a716-446655440000", "title": "Sunny 2BR in Chelsea", "address": "123 Main St, Apt 4B, New York, NY 10001", "monthlyRent": 2500, "bedrooms": 2, "bathrooms": 1, "available": true, "createdAt": "2026-01-15T10:30:00.000Z" } ], "pagination": { "page": 1, "limit": 20, "total": 42, "totalPages": 3 } }

Create Property

POST /api/v1/properties

Request body:

{ "title": "Sunny 2BR in Chelsea", "address": "123 Main St, Apt 4B, New York, NY 10001", "monthlyRent": 2500, "bedrooms": 2, "bathrooms": 1, "description": "Sunny 2BR with updated kitchen and hardwood floors.", "available": true, "imageUrls": ["https://example.com/photo1.jpg"] }

title is optional for backward compatibility. When omitted, Rentalot derives it from the normalized address. An explicit non-blank title takes precedence.

bedrooms: 0 means Studio. In the property-type development preview, create and update accept optional propertyType with one of house, apartment, condo, townhouse, or room. Existing API clients may omit it, and responses retain null for an unknown type. Supplying a type or type filter while the preview is disabled is rejected rather than silently ignored.

For example, GET /api/v1/properties?bedroomType=studio&propertyType=apartment&propertyType=condo finds Studio apartments or condos when the type preview is enabled. Other supplied filters still apply. Do not combine Studio with a positive minBedrooms unless you intend an empty intersection.

imageUrls is optional for paid plans — if provided, the server queues an async image import and the response includes an imageImport block with a jobId you can poll via GET /properties/:id/images/import/:jobId. Trial requests that provide imageUrls are rejected.

Response (201 Created): Includes a Location: /api/v1/properties/:id header.

{ "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "title": "Sunny 2BR in Chelsea", "address": "123 Main St, Apt 4B, New York, NY 10001", "monthlyRent": 2500, "bedrooms": 2, "bathrooms": 1, "available": true, "createdAt": "2026-01-15T10:30:00.000Z" } }

Get Property

GET /api/v1/properties/:id

Response (200 OK): { "data": <property> }.

Update Property

PATCH /api/v1/properties/:id

Send only the fields you want to update. title may be updated independently. A property cannot be left public unless it has a non-blank title and address, positive monthly rent, and positive bathrooms. Incomplete publication attempts return 422 with actionable readiness details. During the Free Trial, updates are private-only and reject an already-public property or a request that attempts to set isPublic: true.

Response (200 OK): { "data": <updated property> }.

Delete Property

DELETE /api/v1/properties/:id

Soft-delete. Sets deletedAt on the property — the row is hidden from list/get responses but kept in the database for audit and recovery. Returns 204 No Content. During the Free Trial, deletion is limited to private properties without images; paid deletion keeps its existing image-cleanup behavior.

Bulk Create Properties

POST /api/v1/properties/bulk

Submit up to 500 properties in a single request. Processing happens asynchronously — you get a job ID back immediately.

Field names are flexible. You can use camelCase (monthlyRent, bedrooms) or common alternatives from property management tools (rent, beds, street_address, monthly_rent, etc.). Values like "$1,500", "3 BR", and "yes" are coerced automatically. Unknown fields are surfaced in the job result as unmappedFields.

Requires: Pro or Scale plan.

Request body:

{ "properties": [ { "street": "123 Main St", "rent": 1500, "beds": 2, "baths": 1, "city": "Austin" }, { "address": "456 Oak Ave", "monthlyRent": 2000, "bedrooms": 3, "bathrooms": 2 } ] }

Supports Idempotency-Key header.

Response (202 Accepted):

{ "data": { "jobId": "550e8400-e29b-41d4-a716-446655440000", "status": "pending", "total": 2 } }

Get Bulk Import Job Status

GET /api/v1/properties/bulk/:jobId

Poll this endpoint to check progress. You can also subscribe to the bulk_import.completed webhook event.

Response (200 OK):

{ "data": { "jobId": "550e8400-e29b-41d4-a716-446655440000", "status": "completed", "total": 100, "created": 95, "failed": 5, "createdPropertyIds": ["id1", "id2", "..."], "unmappedFields": ["custom_field_x", "internal_id"], "errors": [ { "row": 3, "field": "monthlyRent", "message": "Required", "code": "validation" }, { "row": 98, "message": "Property limit exceeded (100 max for pro plan)", "code": "capacity" } ], "createdAt": "2026-02-19T10:00:00.000Z", "completedAt": "2026-02-19T10:00:05.000Z" } }

status is one of pending, processing, completed, failed.