The Properties API exposes accommodation listings across Costa Rica — hotels, eco-lodges, villas, cabins, glamping, and more. Public read endpoints return paginated results with optional filters. Write operations (create, update, delete) require an authenticated vendor account. All IDs are UUIDs. Responses and cache are invalidated automatically on every write.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/IvanchoDev89/maleku-system/llms.txt
Use this file to discover all available pages before exploring further.
GET /api/v1/properties/
Returns a paginated list of active properties. Results are cached for 5 minutes and keyed by every combination of query parameters.Page number (1-indexed).
Items per page. Maximum 100.
Filter by region name (exact match). Use
GET /api/v1/properties/regions to get a distinct list of available regions.Filter by accommodation type. Accepted values:
hotel, hostel, eco_lodge, resort, villa, apartment, cabin, glamping, boutique, aparthotel.Filter by location category. Accepted values:
beach, mountain, jungle, city, rural, lake.Minimum
base_price (USD).Maximum
base_price (USD).Minimum average rating (0–5).
When
true, returns only featured listings.200
POST /api/v1/properties/
Creates a new property listing. RequiresVENDOR or SUPER_ADMIN role. The vendor’s profile must exist before calling this endpoint. A URL-friendly slug is generated automatically from the property name with a UUID suffix.
Auth: Bearer token — Vendor or SUPER_ADMIN
Rate limit: 10 requests/minute per IP
Request body
201
GET /api/v1/properties/regions
Returns a deduplicated list of all regions where active properties are located. Useful for populating filter dropdowns. Auth: Public Response200
GET /api/v1/properties/vendor/my
Returns the authenticated vendor’s own property listings with pagination. Only accounts with theVENDOR role may call this endpoint.
Auth: Bearer token — Vendor role required
Query parameters: page, page_size (same pagination params as the public list endpoint)
Response 200 — same PaginatedResponse shape as the public list endpoint, scoped to the vendor’s own properties.
GET /api/v1/properties/slug/
Returns a single property by its URL-friendly slug. Response is cached for 10 minutes. Auth: Public Response200 — same PropertyResponse as the UUID lookup
Response 404 — { "detail": "Property not found" }
GET /api/v1/properties/
Returns a single property by UUID with all related rooms, vendor public info, and reviews. Response is cached for 10 minutes. Response200 — Full PropertyResponse with:
rooms[]— list ofRoomSchemaobjects, each containingprice_per_night,weekend_price,extra_guest_price,cleaning_fee,max_guests,bed_type,imagesvendor— public vendor summary (name, rating, total_reviews)- All fields from the property model
404 — { "detail": "Property not found" }
PUT /api/v1/properties/
Updates an existing property. Only the owning vendor or aSUPER_ADMIN may update. All fields are optional; only supplied fields are changed (partial update). Mass-assignment is prevented — only the fields in the ALLOWED_FIELDS list are accepted.
Auth: Bearer token — Owner Vendor or SUPER_ADMIN
Rate limit: 10 requests/minute per IP
Request body — any subset of PropertyUpdate fields, for example:
200 — updated PropertyResponse
DELETE /api/v1/properties/
Soft-deletes the property by settingis_active = false. The record is not removed from the database.
Auth: Bearer token — Owner Vendor or SUPER_ADMIN
Response 200
Maleku uses a soft-delete strategy. When a property is deleted,
is_active is set to false and the record remains in the database. A deleted_at timestamp field is also present on the model for full audit support. Deleted properties are excluded from all public listing queries automatically.POST /api/v1/properties//images
Uploads an image file to a property. The file is stored in Cloudinary if configured, falling back to local storage. Whenis_cover is true, the uploaded URL also becomes the property’s cover_image.
Auth: Bearer token — Owner Vendor or SUPER_ADMIN
Rate limit: 10 requests/minute per IP
Content-Type: multipart/form-data
| Field | Type | Description |
|---|---|---|
file | binary | Image file (jpg, jpeg, png, gif, webp). Max 10 MB. |
is_cover | boolean | When true, sets this image as the cover. Defaults to false. |
200 — updated PropertyResponse with new image appended to images[] and cover_image set if applicable.
PUT /api/v1/properties//cover
Sets or replaces the cover image URL for a property using an existing URL string (not a file upload). If the URL is not already inimages[], it is appended.
Auth: Bearer token — Owner Vendor or SUPER_ADMIN
Rate limit: 10 requests/minute per IP
Query parameter: image_url — the URL to set as cover image.
Response 200 — updated PropertyResponse
DELETE /api/v1/properties//images
Removes an image URL from the property’simages[] array. If the removed URL matches cover_image, the cover is also cleared.
Auth: Bearer token — Owner Vendor or SUPER_ADMIN
Query parameter: image_url — the URL to remove.
Response 200 — updated PropertyResponse
Key Model Fields
The table below describes the most important fields of theProperty model stored in PostgreSQL.
| Field | Type | Description |
|---|---|---|
id | UUID | Primary key |
vendor_id | UUID | FK to vendors |
name | string(255) | Display name |
slug | string(255) | URL-friendly unique identifier |
property_type | enum | hotel, hostel, eco_lodge, resort, villa, apartment, cabin, glamping, boutique, aparthotel |
category | enum | beach, mountain, jungle, city, rural, lake |
address | string(500) | Street address |
latitude / longitude | float | Geographic coordinates |
base_price | numeric(10,2) | Weekday nightly rate (USD) |
weekend_price | numeric(10,2) | Friday/Saturday nightly rate (USD) |
weekly_discount | numeric(5,2) | Percentage discount for stays ≥ 7 nights |
amenities | JSONB array | e.g. ["wifi", "pool", "kitchen"] |
features | JSONB array | e.g. ["ocean_view", "private_pool"] |
cover_image | string(500) | Primary image URL |
images | JSON array | All image URLs |
check_in_time | string | Default "15:00" |
check_out_time | string | Default "11:00" |
is_active | boolean | Controls public visibility |
is_featured | boolean | Highlighted in featured sections |
rating | float | Computed average (0–5) |
deleted_at | timestamp | Set on soft delete |
Room fields (nested in PropertyResponse)
Each room under a property has its own pricing:
| Field | Type | Description |
|---|---|---|
price_per_night | numeric | Base nightly rate |
weekend_price | numeric | Weekend nightly rate |
extra_guest_price | numeric | Per-person surcharge above base occupancy |
cleaning_fee | numeric | One-time cleaning charge |
max_guests | integer | Maximum occupancy |
bed_type | string | e.g. "King", "Twin" |
is_available | boolean | Availability status |