Skip to main content

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.

The Search API powers two distinct discovery modes on the Maleku System platform: a global ILIKE-based search across all content types and a dedicated full-text property search powered by PostgreSQL’s ranked search. Both endpoints are rate-limited to 30 requests per minute per IP. All search endpoints are public — no authentication required.

GET /api/v1/search/

Global search across properties, tours, destinations, and blog posts in parallel. Uses ILIKE pattern matching on names and titles and returns categorised results in a single response.
q
string
required
Search query string. Minimum 1 character, maximum 200 characters. The value is sanitised and escaped before use.
limit
integer
default:"10"
Maximum number of items to return per category (properties, tours, destinations, blog). Range: 1–50.
Response — SearchResponse
{
  "properties": [
    {
      "id": "3f9a1b2c-...",
      "name": "Beachfront Villa Manuel Antonio",
      "slug": "beachfront-villa-manuel-antonio",
      "type": "property",
      "image": "https://cdn.maleku.dev/properties/villa-ma.jpg"
    }
  ],
  "tours": [
    {
      "id": "7d4e2f8a-...",
      "name": "Arenal Volcano Hike",
      "slug": "arenal-volcano-hike",
      "type": "tour",
      "image": "https://cdn.maleku.dev/tours/arenal.jpg"
    }
  ],
  "destinations": [
    {
      "id": "1a2b3c4d-...",
      "name": "Manuel Antonio",
      "slug": "manuel-antonio",
      "type": "destination",
      "image": "https://cdn.maleku.dev/destinations/ma.jpg"
    }
  ],
  "blog": [
    {
      "id": "9e8f7a6b-...",
      "title": "Top Beaches in Costa Rica",
      "slug": "top-beaches-costa-rica",
      "type": "blog",
      "image": "https://cdn.maleku.dev/blog/beaches.jpg"
    }
  ]
}
Example request
curl "https://api.maleku.dev/api/v1/search/?q=arenal&limit=5"

GET /api/v1/search/properties

Full-text search over properties only, using PostgreSQL’s tsvector ranked search with optional filters. Returns results ordered by relevance rank.
q
string
required
Search query. Minimum 1 character, maximum 200 characters.
property_type
string
Filter by property type (e.g. hotel, cabin, villa, hostel).
category
string
Filter by property category (e.g. beachfront, mountain, jungle).
region
string
Filter by Costa Rica region (e.g. Guanacaste, Puntarenas, San José).
min_price
float
Minimum base price (USD).
max_price
float
Maximum base price (USD).
limit
integer
default:"20"
Number of results. Range: 1–100.
Response — TextSearchResponse
{
  "items": [
    {
      "id": "3f9a1b2c-...",
      "name": "Beachfront Villa Manuel Antonio",
      "slug": "beachfront-villa-manuel-antonio",
      "property_type": "villa",
      "category": "beachfront",
      "region": "Puntarenas",
      "city": "Manuel Antonio",
      "cover_image": "https://cdn.maleku.dev/properties/villa-ma.jpg",
      "base_price": 250.00,
      "rating": 4.8,
      "total_reviews": 42,
      "match_type": "text",
      "rank": 0.912
    }
  ],
  "total": 1,
  "query": "beachfront villa"
}

GET /api/v1/search/map

Returns properties and tours with coordinates for the interactive map view. Properties must have non-null latitude and longitude to appear. Tours are always included (coordinates may be null if not set on the tour record). Supports pagination with up to 200 items per page.
property_type
string
Filter map markers by property type.
category
string
Filter properties by category or tours by TourCategory enum value (adventure, beach, wildlife, culture, nature).
region
string
Filter properties by region. Does not apply to tours.
min_price
float
Minimum price filter — applied to base_price for properties and price for tours.
max_price
float
Maximum price filter.
page
integer
default:"1"
Page number. Minimum: 1.
page_size
integer
default:"50"
Items per page. Range: 1–200. Values above 200 are clamped to 200.
Response — MapDataResponse
{
  "properties": [
    {
      "id": "3f9a1b2c-...",
      "name": "Beachfront Villa",
      "slug": "beachfront-villa",
      "property_type": "villa",
      "category": "beachfront",
      "region": "Puntarenas",
      "city": "Manuel Antonio",
      "address": "Km 7 Quepos-Manuel Antonio",
      "latitude": 9.3968,
      "longitude": -84.1397,
      "cover_image": "https://cdn.maleku.dev/properties/villa.jpg",
      "images": ["https://...", "https://..."],
      "base_price": 250.00,
      "weekend_price": 310.00,
      "rating": 4.8,
      "total_reviews": 42,
      "min_guests": 1,
      "max_guests": 8,
      "amenities": ["wifi", "pool", "kitchen", "parking"]
    }
  ],
  "tours": [
    {
      "id": "7d4e2f8a-...",
      "name": "Arenal Volcano Hike",
      "slug": "arenal-volcano-hike",
      "category": "adventure",
      "difficulty": "moderate",
      "location": "La Fortuna",
      "latitude": null,
      "longitude": null,
      "cover_image": "https://cdn.maleku.dev/tours/arenal.jpg",
      "images": [],
      "price": 89.00,
      "duration_hours": 4.0,
      "rating": 4.7,
      "total_reviews": 128,
      "max_group_size": 20
    }
  ],
  "pagination": {
    "page": 1,
    "page_size": 50,
    "total_properties": 142,
    "total_tours": 38,
    "total_pages": 3
  }
}
The Maleku System frontend map is built with Leaflet.js and consumes this exact API response. The MapPropertyItem and MapTourItem shapes are used directly to render map markers and popup cards — keep field names stable.

GET /api/v1/search/map/count

Returns aggregate counts for map markers grouped by region and tour category. Useful for rendering summary overlays and filter badges without fetching all markers. Response — MapCountsResponse
{
  "total_properties": 142,
  "total_tours": 38,
  "by_region": {
    "Guanacaste": 54,
    "Puntarenas": 38,
    "San José": 22
  },
  "by_category": {
    "adventure": 14,
    "wildlife": 9,
    "beach": 7,
    "culture": 5,
    "nature": 3
  }
}

MapPropertyItem Schema

id
string
UUID of the property.
name
string
Display name.
slug
string
URL-friendly identifier used for the public property page.
property_type
string
Type of accommodation (e.g. hotel, villa, cabin, hostel).
category
string | null
Property category (e.g. beachfront, mountain, eco).
region
string | null
Costa Rica region (e.g. Guanacaste, Puntarenas).
city
string | null
City or town.
address
string | null
Street address of the property.
latitude
float | null
WGS-84 latitude. Only properties with non-null coordinates are included.
longitude
float | null
WGS-84 longitude.
cover_image
string | null
Primary image URL.
images
string[]
Up to 4 additional image URLs. Default: [].
base_price
float
Weekday nightly rate in USD. Default: 0.
weekend_price
float
Weekend nightly rate in USD. Default: 0.
rating
float | null
Average review rating (0–5).
total_reviews
integer | null
Total number of approved reviews.
min_guests
integer
Minimum guest count. Default: 1.
max_guests
integer
Maximum guest count. Default: 10.
amenities
string[]
Up to 8 amenity tags returned for map popups (e.g. ["wifi", "pool", "kitchen"]).

MapTourItem Schema

id
string
UUID of the tour.
name
string
Tour display name.
slug
string
URL-friendly identifier.
category
string | null
Tour category enum value: adventure, beach, wildlife, culture, or nature.
difficulty
string | null
Difficulty level: easy, moderate, or hard.
location
string | null
Human-readable location string (e.g. La Fortuna, Manuel Antonio).
latitude
float | null
WGS-84 latitude. May be null if not set on the tour record.
longitude
float | null
WGS-84 longitude.
cover_image
string | null
Primary image URL.
images
string[]
Up to 4 additional image URLs. Default: [].
price
float
Tour price per person in USD. Default: 0.
duration_hours
float
Duration in decimal hours (e.g. 4.5 = 4 hours 30 minutes). Default: 0.
rating
float | null
Average review rating (0–5).
total_reviews
integer | null
Total number of approved reviews.
max_group_size
integer
Maximum number of participants per booking. Default: 20.

Build docs developers (and LLMs) love