> ## Documentation Index
> Fetch the complete documentation index at: https://docs.privetag.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Recommend

> Get context-aware activity recommendations

# Get Recommendations

<Note>
  This endpoint returns activities ranked by **Ground Truth** data - real user behavior, not assumptions.
</Note>

## Use This Endpoint When

<CardGroup cols={2}>
  <Card title="User asks about activities" icon="question">
    * "What should we do today?"
    * "Any family activities nearby?"
    * "Things to do in Bangkok"
  </Card>

  <Card title="Context-aware needs" icon="cloud-sun">
    * "It's raining, what's good?"
    * "Romantic dinner for tonight"
    * "Kid-friendly activities"
  </Card>
</CardGroup>

## Request

<ParamField body="user_profile" type="object" required>
  User preferences and characteristics

  <Expandable title="Properties">
    <ParamField body="travel_type" type="string" required>
      One of: `family`, `couple`, `solo`, `business`, `friends`
    </ParamField>

    <ParamField body="nationality" type="string">
      ISO 3166-1 alpha-2 code (e.g., `KR`, `US`, `TH`)
    </ParamField>

    <ParamField body="interests" type="string[]">
      Categories: `spa`, `dinner`, `theme-park`, `zoo`, `aquarium`, `adventure`, `cultural`, `nightlife`
    </ParamField>

    <ParamField body="budget" type="string">
      One of: `budget`, `mid`, `luxury`
    </ParamField>

    <ParamField body="age_group" type="string">
      One of: `family`, `young_adult`, `adult`, `senior`
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="location" type="object" required>
  User's current or target location

  <Expandable title="Properties">
    <ParamField body="city" type="string">
      City name (e.g., `Bangkok`, `Phuket`)
    </ParamField>

    <ParamField body="lat" type="number">
      Latitude for weather data and distance calculation
    </ParamField>

    <ParamField body="lon" type="number">
      Longitude for weather data and distance calculation
    </ParamField>

    <ParamField body="hotel_id" type="string">
      For hotel-specific rates and activities
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="filters" type="object">
  Additional filtering options

  <Expandable title="Properties">
    <ParamField body="is_indoor" type="boolean">
      Filter for indoor activities (weather-appropriate)
    </ParamField>

    <ParamField body="difficulty" type="string">
      One of: `easy`, `moderate`, `challenging`
    </ParamField>

    <ParamField body="max_price" type="number">
      Maximum price in THB
    </ParamField>

    <ParamField body="categories" type="string[]">
      Specific categories to include
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="limit" type="number" default="10">
  Maximum number of recommendations (1-20)
</ParamField>

<ParamField body="include_flash_deals" type="boolean" default="true">
  Include same-day flash deals (30-50% off)
</ParamField>

## Response

<ResponseField name="success" type="boolean">
  Whether the request was successful
</ResponseField>

<ResponseField name="data" type="object">
  <Expandable title="Properties">
    <ResponseField name="recommendations" type="array">
      List of recommended activities

      <Expandable title="Activity Object">
        <ResponseField name="id" type="string">
          Unique activity identifier (use in `/execute_booking`)
        </ResponseField>

        <ResponseField name="title" type="string">
          Activity title in user's language
        </ResponseField>

        <ResponseField name="description" type="string">
          Detailed description
        </ResponseField>

        <ResponseField name="category" type="string">
          Activity category
        </ResponseField>

        <ResponseField name="price" type="number">
          Price in local currency
        </ResponseField>

        <ResponseField name="currency" type="string">
          Currency code (e.g., `THB`, `USD`)
        </ResponseField>

        <ResponseField name="relevance_score" type="number">
          0-100 score based on context matching
        </ResponseField>

        <ResponseField name="recommendation_reason" type="string">
          Human-readable explanation of why this was recommended
        </ResponseField>

        <ResponseField name="is_flash_deal" type="boolean">
          Whether this is a limited-time deal
        </ResponseField>

        <ResponseField name="original_price" type="number">
          Original price (if flash deal)
        </ResponseField>

        <ResponseField name="images" type="string[]">
          Array of image URLs
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="context" type="object">
      Context information for tracking

      <Expandable title="Properties">
        <ResponseField name="log_id" type="string">
          **Important**: Pass this to `/execute_booking` for conversion tracking
        </ResponseField>

        <ResponseField name="user_profile_summary" type="string">
          Summary of matched user profile
        </ResponseField>

        <ResponseField name="environment_summary" type="string">
          Current environment context (weather, time, etc.)
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

## Examples

### Family Trip in Bangkok

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.privetag.com/api/b2a/recommend \
    -H "x-api-key: pk_a1b2c3..." \
    -H "Content-Type: application/json" \
    -d '{
      "user_profile": {
        "travel_type": "family",
        "interests": ["theme-park", "zoo", "aquarium"]
      },
      "location": {
        "city": "Bangkok",
        "lat": 13.7563,
        "lon": 100.5018
      },
      "filters": {
        "difficulty": "easy"
      },
      "limit": 5
    }'
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://api.privetag.com/api/b2a/recommend",
      headers={
          "x-api-key": "pk_a1b2c3...",
          "Content-Type": "application/json"
      },
      json={
          "user_profile": {
              "travel_type": "family",
              "interests": ["theme-park", "zoo", "aquarium"]
          },
          "location": {
              "city": "Bangkok",
              "lat": 13.7563,
              "lon": 100.5018
          },
          "filters": {
              "difficulty": "easy"
          },
          "limit": 5
      }
  )

  recommendations = response.json()
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.privetag.com/api/b2a/recommend', {
    method: 'POST',
    headers: {
      'x-api-key': 'pk_a1b2c3...',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      user_profile: {
        travel_type: 'family',
        interests: ['theme-park', 'zoo', 'aquarium']
      },
      location: {
        city: 'Bangkok',
        lat: 13.7563,
        lon: 100.5018
      },
      filters: {
        difficulty: 'easy'
      },
      limit: 5
    })
  });

  const recommendations = await response.json();
  ```
</CodeGroup>

### Rainy Day Recommendations

When lat/lon is provided, the API automatically fetches weather data:

```json theme={null}
{
  "user_profile": {
    "travel_type": "couple"
  },
  "location": {
    "lat": 7.8804,
    "lon": 98.3923
  },
  "filters": {
    "is_indoor": true
  }
}
```

## Response Example

```json theme={null}
{
  "success": true,
  "data": {
    "recommendations": [
      {
        "id": "act_abc123",
        "title": "Safari World Bangkok",
        "description": "World-class zoo with safari and marine park",
        "category": "zoo",
        "price": 1500,
        "currency": "THB",
        "relevance_score": 95,
        "recommendation_reason": "Perfect for families - interactive animal experiences",
        "is_flash_deal": false,
        "images": ["https://cdn.privetag.com/activities/safari-world-1.jpg"]
      },
      {
        "id": "act_def456",
        "title": "Dream World Theme Park",
        "description": "Exciting rides and attractions for all ages",
        "category": "theme-park",
        "price": 1200,
        "currency": "THB",
        "relevance_score": 92,
        "recommendation_reason": "Family-friendly theme park with easy rides",
        "is_flash_deal": true,
        "original_price": 1800
      }
    ],
    "context": {
      "log_id": "ctx_xyz789",
      "user_profile_summary": "family, interested in theme-park, zoo, aquarium",
      "environment_summary": "Bangkok, sunny, 32°C, afternoon"
    }
  }
}
```

## Relevance Score Factors

The `relevance_score` (0-100) is calculated from:

| Factor                  | Weight | Description                                           |
| ----------------------- | ------ | ----------------------------------------------------- |
| User Profile Match      | 30%    | How well activity matches travel\_type and interests  |
| Ground Truth Data       | 25%    | Real visit data from similar user profiles            |
| Weather Appropriateness | 20%    | Indoor/outdoor suitability for current weather        |
| Time Appropriateness    | 15%    | Activity timing (morning activity, dinner spot, etc.) |
| Price Match             | 10%    | Budget alignment                                      |

<Info>
  **Ground Truth Advantage**: Our recommendations improve over time as we collect more NFC-verified visit data. The more your users book and visit, the better the recommendations become.
</Info>

## Error Responses

| Code               | Description                                       |
| ------------------ | ------------------------------------------------- |
| `INVALID_LOCATION` | City not found or coordinates out of service area |
| `INVALID_PROFILE`  | Missing required user\_profile fields             |
| `NO_ACTIVITIES`    | No activities found matching criteria             |

## Next Steps

<Card title="Execute Booking" icon="ticket" href="/api-reference/b2a/execute-booking">
  Once user selects an activity, execute the booking
</Card>
