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.

Destinations are the editorial backbone of the Maleku System platform — rich travel guides curated by administrators that cover Costa Rica’s regions, provinces, cantons, and districts. Each destination entry holds geographic coordinates, cultural content, practical travel information, media galleries, and SEO metadata. Public read endpoints are cached to maximise performance; write operations require elevated roles and automatically invalidate the cache.
Destination records are admin-managed CMS content. Only users with the admin or super_admin role can create, update, or delete destinations. All public read endpoints are unauthenticated.

GET /api/v1/destinations/

List active destinations with optional filtering, sorting, and pagination. When page_size is 0 (default), the endpoint returns a flat array and caches the result for 600 seconds. When page_size > 0, paginated mode is activated and caching is skipped to ensure accurate totals.
region
string
Filter by Costa Rica region (e.g. Guanacaste, Puntarenas, Heredia).
province
string
Filter by province.
When true, returns only destinations marked as featured.
Searches across name and description using ILIKE pattern matching.
active_only
boolean
default:"true"
Exclude soft-deleted and inactive destinations.
page
integer
default:"1"
Page number (requires page_size > 0 to activate paginated mode).
page_size
integer
default:"0"
Items per page. Range: 0–100. Set to 0 for a flat unpaginated list.
sort_by
string
default:"order"
Sort field. Allowed values: order, name, created_at, region, province, is_featured.
sort_order
string
default:"asc"
Sort direction: asc or desc.
Flat list response (when page_size=0)
[
  {
    "id": "1a2b3c4d-e5f6-...",
    "name": "Manuel Antonio",
    "slug": "manuel-antonio",
    "country": "Costa Rica",
    "region": "Puntarenas",
    "province": "Puntarenas",
    "canton": "Quepos",
    "district": "Manuel Antonio",
    "latitude": 9.3968,
    "longitude": -84.1397,
    "zoom": 12,
    "description": "A jewel of Costa Rica's Pacific coast...",
    "highlights": ["National Park", "Pristine Beaches", "Wildlife"],
    "things_to_do": ["Kayaking", "Hiking", "Snorkeling"],
    "image": "https://cdn.maleku.dev/destinations/manuel-antonio.jpg",
    "is_featured": true,
    "is_active": true,
    "order": 1,
    "created_at": "2024-01-10T08:00:00Z",
    "updated_at": "2024-03-15T12:00:00Z"
  }
]

GET /api/v1/destinations/hierarchy

Returns a geographic hierarchy tree of active destinations grouped by region and province with item counts. Result is cached for 600 seconds.
[
  {
    "name": "Guanacaste",
    "children": [
      { "name": "Liberia", "count": 8 },
      { "name": "Nicoya", "count": 5 }
    ]
  },
  {
    "name": "Puntarenas",
    "children": [
      { "name": "Quepos", "count": 12 },
      { "name": "Osa", "count": 4 }
    ]
  }
]

GET /api/v1/destinations/

Retrieve a single destination by its UUID or URL slug. The response is cached for 900 seconds under both the ID-based and slug-based cache keys. Path parameter: UUID or slug string (e.g. manuel-antonio or 1a2b3c4d-...). Example request
curl "https://api.maleku.dev/api/v1/destinations/manuel-antonio"
Response — DestinationResponse
{
  "id": "1a2b3c4d-e5f6-...",
  "name": "Manuel Antonio",
  "slug": "manuel-antonio",
  "country": "Costa Rica",
  "region": "Puntarenas",
  "province": "Puntarenas",
  "canton": "Quepos",
  "district": "Manuel Antonio",
  "latitude": 9.3968,
  "longitude": -84.1397,
  "zoom": 12,
  "description": "A jewel of Costa Rica's Pacific coast...",
  "highlights": ["National Park", "Pristine Beaches", "Wildlife"],
  "things_to_do": ["Kayaking", "Hiking", "Snorkeling"],
  "culture": "Rich Bribri and Brunca heritage...",
  "gastronomy": "Fresh ceviche and rice with seafood...",
  "history": "Originally a fishing village...",
  "best_time": "December to April (dry season)",
  "weather_info": "Tropical humid, 26–32°C year-round",
  "getting_there": "90 min drive from San José or Nature Air flight to Quepos",
  "local_tips": "Book national park tickets in advance",
  "safety_info": "Safe for tourists; watch valuables on the beach",
  "language": "Spanish",
  "currency": "Costa Rican Colón (CRC) / USD accepted",
  "timezone": "America/Costa_Rica",
  "phone_code": "+506",
  "visa_info": "Most nationalities do not require a visa for stays up to 90 days",
  "emergency_numbers": ["911", "1-800-TOURISM"],
  "image": "https://cdn.maleku.dev/destinations/manuel-antonio.jpg",
  "gallery": ["https://...", "https://..."],
  "videos": [],
  "featured_photo": "https://cdn.maleku.dev/destinations/ma-hero.jpg",
  "seo_title": "Manuel Antonio — Beaches & National Park | Maleku",
  "seo_description": "Explore Manuel Antonio National Park...",
  "seo_keywords": ["manuel antonio", "costa rica beaches", "national park"],
  "is_featured": true,
  "is_active": true,
  "order": 1,
  "created_at": "2024-01-10T08:00:00Z",
  "updated_at": "2024-03-15T12:00:00Z",
  "deleted_at": null
}

POST /api/v1/destinations/

Create a new destination. Requires super_admin role. Auto-generates a slug from the name field if not provided. Rate-limited to 10 requests per minute. Request body — DestinationCreate
{
  "name": "Tortuguero",
  "description": "A remote Caribbean paradise...",
  "country": "Costa Rica",
  "region": "Limón",
  "province": "Limón",
  "canton": "Pococí",
  "latitude": 10.5385,
  "longitude": -83.5027,
  "zoom": 13,
  "highlights": ["Sea Turtle Nesting", "Canals", "Rainforest"],
  "image": "https://cdn.maleku.dev/destinations/tortuguero.jpg",
  "is_featured": false,
  "order": 12
}
Returns 201 Created with the full DestinationResponse.

PUT /api/v1/destinations/

Update an existing destination. Requires admin or super_admin role. Only fields included in the request body are updated (partial update). Invalidates all destination cache tags on success. Rate-limited to 10 requests per minute.

DELETE /api/v1/destinations/

Soft-delete a destination — sets is_active = false and records a deleted_at timestamp. Requires super_admin role. The record is excluded from all list and detail queries after deletion but remains in the database. Response
{ "message": "Destination deleted successfully" }

PUT /api/v1/destinations//order

Update the display sort order of a destination. Requires super_admin role. Pass the new integer order value as a query parameter.
curl -X PUT "https://api.maleku.dev/api/v1/destinations/{id}/order?order=3" \
  -H "Authorization: Bearer <token>"

Key Destination Fields

id
UUID
Unique identifier.
name
string
Display name. Minimum 2 characters, maximum 255.
slug
string
URL-friendly unique identifier. Auto-generated from name if omitted.
region
string | null
Top-level geographic region (e.g. Guanacaste).
province
string | null
Costa Rica province.
description
string | null
Main editorial description. HTML is stripped before storage.
highlights
string[]
Short list of notable highlights for use in cards and previews.
things_to_do
string[]
Activity suggestions for the destination.
latitude / longitude
float | null
WGS-84 coordinates. Latitude must be −90 to 90; longitude −180 to 180.
image
string | null
Primary image URL (must start with http://, https://, or /).
Array of additional image URLs.
When true the destination is promoted in hero sections and featured lists.
order
integer
Display sort order. Lower values appear first. Default: 0.

Trip Planner

Authenticated users can build multi-destination itineraries using the Trip Planner API. Plans group individual items (accommodations, tours, transport, flights, boats) by day index and compute a live price breakdown including package discounts and commission splits.

Trip Plan Endpoints

MethodPathDescription
POST/api/v1/trip_planner/plansCreate a new trip plan (status: draft)
GET/api/v1/trip_planner/plansList the authenticated user’s plans
GET/api/v1/trip_planner/plans/{plan_id}Get plan with all items
PUT/api/v1/trip_planner/plans/{plan_id}Update plan metadata
DELETE/api/v1/trip_planner/plans/{plan_id}Delete a plan
POST/api/v1/trip_planner/plans/{plan_id}/itemsAdd an item to a plan
PUT/api/v1/trip_planner/items/{item_id}Update an item
DELETE/api/v1/trip_planner/items/{item_id}Remove an item from a plan
GET/api/v1/trip_planner/plans/{plan_id}/priceGet full price breakdown
POST/api/v1/trip_planner/plans/{plan_id}/repriceRecalculate all item prices
Create plan request body
{
  "name": "Costa Rica Adventure Week",
  "start_date": "2025-02-10",
  "end_date": "2025-02-17",
  "travelers": 2,
  "budget_min": 1500,
  "budget_max": 4000,
  "notes": "Focus on wildlife and nature tours"
}
Plan statuses: draftpricingreadybooked Item reference_type values: property, tour, transportation, flight, vehicle, boat Item item_type values: accommodation, tour, transport, car_rental, boat, flight, meal, other Each item automatically fetches the current price from the referenced listing on creation. Use POST /plans/{id}/reprice to refresh all prices after date changes.

Build docs developers (and LLMs) love