Skip to contentSkip to Content
API ReferenceProperties

Properties API

CRUD endpoints for managing your property listings programmatically.

List Properties

GET /api/v1/properties

Returns a paginated list of your properties.

Query Parameters:

ParameterTypeDescription
pagenumberPage number (default: 1)
limitnumberItems per page (default: 20, max: 100)

Response:

{ "data": [ { "id": "prop_abc123", "address": "123 Main St, Apt 4B, New York, NY 10001", "rent": 2500, "bedrooms": 2, "bathrooms": 1, "available": true, "createdAt": "2025-01-15T10:30:00Z" } ], "pagination": { "page": 1, "limit": 20, "total": 42 } }

Create Property

POST /api/v1/properties

Request Body:

{ "address": "123 Main St, Apt 4B, New York, NY 10001", "rent": 2500, "bedrooms": 2, "bathrooms": 1, "description": "Sunny 2BR with updated kitchen and hardwood floors.", "available": true }

Get Property

GET /api/v1/properties/:id

Update Property

PATCH /api/v1/properties/:id

Send only the fields you want to update.

Delete Property

DELETE /api/v1/properties/:id

Returns 204 No Content on success.

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 our camelCase field names (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 automatically coerced.

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 } ] }

Response (202 Accepted):

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

Supports Idempotency-Key header.

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:

{ "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" } }

Batch Presign Image Upload

POST /api/v1/properties/:id/images/presign-batch

Get multiple presigned R2 upload URLs at once (max 20 per request).

Request Body:

{ "images": [ { "fileName": "kitchen.jpg", "contentType": "image/jpeg", "sizeBytes": 512000 }, { "fileName": "bedroom.png", "contentType": "image/png", "sizeBytes": 1024000 } ] }

Response:

{ "data": [ { "fileName": "kitchen.jpg", "uploadUrl": "https://...", "r2Key": "images/..." }, { "fileName": "bedroom.png", "uploadUrl": "https://...", "r2Key": "images/..." } ] }

After receiving the presigned URLs, PUT each file directly to its uploadUrl.

Batch Confirm Image Upload

POST /api/v1/properties/:id/images/confirm-batch

Confirm multiple image uploads at once after uploading to R2.

Request Body:

{ "images": [ { "r2Key": "images/...", "contentType": "image/jpeg", "sizeBytes": 512000, "altText": "Kitchen" }, { "r2Key": "images/...", "contentType": "image/png", "sizeBytes": 1024000 } ] }

Response:

{ "data": [ { "id": "img-uuid-1", "url": "https://cdn.rentalot.ai/...", "altText": "Kitchen", "order": 0 }, { "id": "img-uuid-2", "url": "https://cdn.rentalot.ai/...", "altText": null, "order": 1 } ] }

Supports Idempotency-Key header.