Skip to content

MacumbaTravel API Documentation

Overview

MacumbaTravel is a budget-first travel planning API powered by AI. It provides recommendations for travel destinations based on user preferences, budget constraints, and other parameters.

Base URL

All API endpoints are prefixed with: /api/v1

Authentication

Most endpoints can be accessed by both authenticated and unauthenticated users, but unauthenticated users are subject to rate limits.

Authentication Endpoints

Register a new user

POST /auth/register

Request body:

{
  "email": "user@example.com",
  "password": "securepassword",
  "name": "John Doe"
}

Response:

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "bearer"
}

Login

POST /auth/login

Request body (form data):

username: user@example.com
password: securepassword

Response:

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "bearer"
}

Verify Email

GET /auth/verify-email/{token}

Response:

{
  "message": "Email verified successfully"
}

Request Password Reset

POST /auth/password-reset

Request body:

{
  "email": "user@example.com"
}

Response:

{
  "message": "If your email is registered, you will receive a password reset link"
}

Confirm Password Reset

POST /auth/password-reset-confirm

Request body:

{
  "token": "reset-token",
  "new_password": "newsecurepassword"
}

Response:

{
  "message": "Password updated successfully"
}

Travel Recommendations

Get Initial Recommendations

POST /recommendations

Request body:

{
  "budget": 2000,
  "from_date": "2025-05-01",
  "to_date": "2025-05-08",
  "departure_city": "Sydney",
  "preferences": ["beach", "food", "culture"],
  "max_travel_time": 8,
  "max_results": 5,
  "travelers": 2,
  "destination": null
}

Response:

[
  {
    "id": "rec_123456",
    "destination": "Bali, Indonesia",
    "description": "A beautiful island known for its beaches, culture, and cuisine",
    "estimated_cost": 1800,
    "flight_time": 6.5,
    "thumbnail_image": "https://example.com/images/bali.jpg",
    "highlights": ["Beaches", "Temples", "Food scene"]
  },
  {
    "id": "rec_123457",
    "destination": "Tokyo, Japan",
    "description": "A vibrant metropolis blending tradition and innovation",
    "estimated_cost": 1950,
    "flight_time": 9.5,
    "thumbnail_image": "https://example.com/images/tokyo.jpg",
    "highlights": ["Food", "Technology", "Culture"]
  }
]

Get Detailed Recommendation

GET /recommendations/{recommendation_id}/enrich

Response:

{
  "destination": "Bali, Indonesia",
  "description": "A beautiful island known for its beaches, culture, and cuisine",
  "estimated_cost": 1800,
  "flight_time": 6.5,
  "thumbnail_image": "https://example.com/images/bali.jpg",
  "highlights": ["Beaches", "Temples", "Food scene"],
  "detailed_itinerary": [
    {
      "day": 1,
      "activities": [
        {
          "name": "Arrive in Denpasar",
          "description": "Check into your hotel in Seminyak",
          "cost_estimate": 50
        },
        {
          "name": "Sunset at Seminyak Beach",
          "description": "Enjoy dinner at a beachfront restaurant",
          "cost_estimate": 30
        }
      ]
    },
    {
      "day": 2,
      "activities": [
        {
          "name": "Ubud Day Trip",
          "description": "Visit the Monkey Forest and Rice Terraces",
          "cost_estimate": 80
        }
      ]
    }
  ],
  "accommodation_options": [
    {
      "name": "Budget Hostel",
      "description": "Shared dormitory",
      "cost_per_night": 20,
      "total_cost": 140
    },
    {
      "name": "Mid-range Hotel",
      "description": "Private room with pool access",
      "cost_per_night": 60,
      "total_cost": 420
    },
    {
      "name": "Luxury Villa",
      "description": "Private villa with pool",
      "cost_per_night": 150,
      "total_cost": 1050
    }
  ],
  "transportation": {
    "flights": {
      "outbound": {
        "departure": "Sydney",
        "arrival": "Denpasar",
        "duration": "6h 30m",
        "cost_estimate": 450
      },
      "return": {
        "departure": "Denpasar",
        "arrival": "Sydney",
        "duration": "6h 45m",
        "cost_estimate": 450
      }
    },
    "local": [
      {
        "type": "Taxi from airport",
        "cost_estimate": 20
      },
      {
        "type": "Daily scooter rental",
        "cost_estimate": 10,
        "total_cost": 70
      }
    ]
  },
  "budget_breakdown": {
    "flights": 900,
    "accommodation": 420,
    "local_transportation": 90,
    "food": 280,
    "activities": 110,
    "total": 1800
  },
  "travel_tips": [
    "Exchange money at official money changers",
    "Negotiate prices for souvenirs",
    "Try the local coffee"
  ],
  "weather_forecast": {
    "average_temperature": 28,
    "precipitation_chance": "low",
    "summary": "Warm and sunny with occasional afternoon showers"
  }
}

Save a Recommendation

POST /recommendations/{recommendation_id}/save

Request body:

{
  "name": "Bali Trip 2025",
  "notes": "Anniversary trip",
  "is_public": false
}

Response:

{
  "id": 123,
  "user_id": 456,
  "name": "Bali Trip 2025",
  "search_params": {
    "budget": 2000,
    "from_date": "2025-05-01",
    "to_date": "2025-05-08",
    "departure_city": "Sydney",
    "preferences": ["beach", "food", "culture"]
  },
  "results": {
    "destination": "Bali, Indonesia",
    "estimated_cost": 1800
  },
  "enriched_results": {
    "detailed_itinerary": [...],
    "accommodation_options": [...],
    "transportation": {...}
  },
  "notes": "Anniversary trip",
  "is_public": false,
  "created_at": "2025-04-05T18:44:36+11:00"
}

Get Flight Price Information

POST /flight-price

Request body:

{
  "origin": "SYD",
  "destination": "DPS"
}

Response:

{
  "origin": "SYD",
  "destination": "DPS",
  "price": 450,
  "currency": "USD",
  "flight_time": "6h 30m",
  "airlines": ["Qantas", "Jetstar"],
  "best_time_to_book": "2-3 months in advance"
}

Search Destinations

POST /destinations

Request body:

{
  "origin": "SYD",
  "budget": 2000
}

Response:

{
  "destinations": [
    {
      "code": "DPS",
      "name": "Bali, Indonesia",
      "price": 450,
      "flight_time": "6h 30m"
    },
    {
      "code": "HKT",
      "name": "Phuket, Thailand",
      "price": 500,
      "flight_time": "9h 15m"
    }
  ]
}

Get Random Recommendations

GET /random-recommendations?limit=3&location=Sydney

Response:

[
  {
    "id": "rec_123456",
    "destination": "Bali, Indonesia",
    "description": "A beautiful island known for its beaches, culture, and cuisine",
    "estimated_cost": 1800,
    "flight_time": 6.5,
    "thumbnail_image": "https://example.com/images/bali.jpg"
  },
  {
    "id": "rec_123457",
    "destination": "Tokyo, Japan",
    "description": "A vibrant metropolis blending tradition and innovation",
    "estimated_cost": 1950,
    "flight_time": 9.5,
    "thumbnail_image": "https://example.com/images/tokyo.jpg"
  },
  {
    "id": "rec_123458",
    "destination": "Auckland, New Zealand",
    "description": "A city surrounded by natural beauty",
    "estimated_cost": 1200,
    "flight_time": 3.5,
    "thumbnail_image": "https://example.com/images/auckland.jpg"
  }
]

Saved Trips

Get User's Saved Trips

GET /saved-trips

Response:

[
  {
    "id": 123,
    "name": "Bali Trip 2025",
    "destination": "Bali, Indonesia",
    "from_date": "2025-05-01",
    "to_date": "2025-05-08",
    "budget": 2000,
    "created_at": "2025-04-05T18:44:36+11:00"
  },
  {
    "id": 124,
    "name": "Tokyo Adventure",
    "destination": "Tokyo, Japan",
    "from_date": "2025-06-15",
    "to_date": "2025-06-25",
    "budget": 3000,
    "created_at": "2025-04-01T10:22:15+11:00"
  }
]

Get Saved Trip Details

GET /saved-trips/{trip_id}

Response:

{
  "id": 123,
  "user_id": 456,
  "name": "Bali Trip 2025",
  "search_params": {
    "budget": 2000,
    "from_date": "2025-05-01",
    "to_date": "2025-05-08",
    "departure_city": "Sydney",
    "preferences": ["beach", "food", "culture"]
  },
  "results": {
    "destination": "Bali, Indonesia",
    "estimated_cost": 1800
  },
  "enriched_results": {
    "detailed_itinerary": [...],
    "accommodation_options": [...],
    "transportation": {...}
  },
  "notes": "Anniversary trip",
  "is_public": false,
  "created_at": "2025-04-05T18:44:36+11:00"
}

Rate Limiting

Unauthenticated users are limited to a configurable number of queries within a time period (default: 3 queries per day).

Rate limit headers are included in responses: - X-Rate-Limit-Limit: Maximum number of requests allowed in the period - X-Rate-Limit-Remaining: Number of requests remaining in the current period - X-Rate-Limit-Reset: Unix timestamp when the rate limit will reset

Check Rate Limit Status

GET /rate-limit

Response:

{
  "authenticated": false,
  "queries_left": 2,
  "rate_limit": 3,
  "period": "day",
  "reset_time": "2025-04-06T00:00:00Z"
}

Health and Metrics

Service Health Check

GET /service/health

Response:

{
  "status": "healthy",
  "services": {
    "primary": {
      "provider": "claude",
      "status": "healthy"
    },
    "fallback": {
      "provider": "gemini",
      "status": "healthy"
    }
  }
}

Application Readiness Check

GET /ready

Response:

{
  "status": "ready",
  "services": {
    "database": "connected",
    "ai_service": "connected (claude)"
  }
}

Performance Metrics

GET /metrics/performance

Response:

{
  "metrics": {
    "/api/v1/recommendations": {
      "avg_duration": 1.25,
      "min_duration": 0.8,
      "max_duration": 2.5,
      "p95_duration": 2.1,
      "success_count": 120,
      "error_count": 5,
      "total_count": 125,
      "last_updated": "2025-04-05T18:30:22+11:00"
    }
  },
  "timestamp": "2025-04-05T18:44:36+11:00"
}

Cache Management

Clear Cache

POST /cache/clear

Request body:

{
  "service": "recommendations"
}

Response:

{
  "status": "success",
  "message": "Cache cleared for recommendations service",
  "timestamp": "2025-04-05T18:44:36+11:00"
}

Error Responses

All error responses follow this format:

{
  "detail": "Error message",
  "path": "/api/v1/endpoint"
}

Common HTTP status codes: - 400 Bad Request: Invalid input parameters - 401 Unauthorized: Authentication required - 403 Forbidden: Insufficient permissions - 404 Not Found: Resource not found - 429 Too Many Requests: Rate limit exceeded - 500 Internal Server Error: Server-side error

AI Recommendation Algorithm

The MacumbaTravel recommendation algorithm uses a combination of factors to generate personalized travel recommendations:

  1. Budget Analysis: Analyzes the user's budget to find destinations where the total cost (flights, accommodation, food, activities) fits within the specified amount.

  2. Preference Matching: Matches user preferences (beach, food, culture, etc.) with destination attributes using a weighted scoring system.

  3. Travel Time Constraints: Filters destinations based on flight time from the departure city.

  4. Seasonality: Considers the time of year and typical weather patterns for potential destinations.

  5. Popularity and Safety: Incorporates destination popularity and safety ratings.

The algorithm follows these steps:

  1. Initial Filtering: Filter destinations based on hard constraints (budget, travel time, etc.)
  2. Preference Scoring: Score remaining destinations based on preference matching
  3. Ranking: Rank destinations by score and select the top N results
  4. Enrichment: For selected destinations, generate detailed itineraries and cost breakdowns

The AI models (Claude or Gemini) are used to: - Generate natural language descriptions of destinations - Create personalized itineraries based on preferences - Provide local insights and travel tips - Suggest accommodation options at different price points

The system uses a caching layer to improve performance for similar queries and to reduce dependency on external AI services.

AI Integration

The API integrates with multiple AI providers to generate travel recommendations:

  1. Primary AI Provider: Gemini (Google) - Gemini 2.0 Flash model
  2. Fallback AI Provider: Claude (Anthropic) - Claude 3.5 Sonnet model

The AI models are used to: - Generate realistic travel recommendations based on user preferences and budget - Consider budget constraints with proper tier classification (ultra-budget, budget, mid-range, luxury) - Suggest activities based on destination and preferences with accurate cost estimates - Provide budget-appropriate accommodations and transportation options - Generate recommendations optimized for speed (~4.5 seconds average response time)

Recommendation System Architecture

The system uses a two-tier approach for optimal performance:

1. Initial Recommendations (Fast)

  • Optimized for speed (~4.5 second response time)
  • Provides basic recommendation data without images
  • Available to both authenticated and anonymous users
  • Results are cached for performance

2. Enrichment (Detailed)

  • Provides comprehensive destination details
  • Includes accommodations, transportation options, activities, and images
  • Requires the recommendation to be stored from initial request
  • Available primarily for authenticated users

Cache System

The API uses a PostgreSQL-based cache system that: - Provides cost-effective caching (saves ~$110/month vs Redis) - Stores both initial recommendations and search parameters for enrichment - Uses TTL (Time To Live) for automatic cache expiration - Supports both simple and complex data structures via JSONB - Includes fault-tolerant design that doesn't break the application if cache is unavailable

Budget Calculation

The system implements intelligent budget analysis: - Ultra-budget: <$50/day per person - Budget: $50-100/day per person
- Mid-range: $100-200/day per person - Luxury: $200+/day per person

Budget calculations include: - Transportation costs (flights, local transport) - Accommodation options at different price points - Food and dining estimates based on destination - Activity and attraction costs - Local transportation within destination