Skip to content

3. APIs and Controller

Gabriel Ernesto Mora edited this page Dec 7, 2025 · 7 revisions

API

USER ENDPOINTS

Create User

This endpoint allows new users to register by creating a user account with a username, password, and optional personal preferences. The password is securely hashed before storage, and a JWT access token is generated upon successful registration.

Endpoint: POST /create_user

Key Container Description
username JSON Unique username for the user (case-insensitive)
password JSON Plaintext password that will be hashed
fullname JSON User’s full name
likes JSON (Optional) User’s general travel likes/preferences
dislikes JSON (Optional) User’s general travel dislikes/preferences

Response: Returns a JSON object containing a success message, JWT access token, and user details.

Response Format:

{
        "message": "User created successfully",
        "access_token": access_token,
        "user": {
            "id": new_user.user_id,
            "username": new_user.username,
            "firstname": new_user.firstname,
            "lastname": new_user.lastname,
            "likes": new_user.likes,
            "dislikes": new_user.dislikes
        }
}

Login User

This endpoint authenticates a user by verifying their username and password. Upon successful authentication, it generates a new JWT token for authorization in future requests.

Endpoint: POST /login

Key Container Description
username JSON Registered username of the user
password JSON Password associated with the username

Response: Returns a JSON object with the login success message, JWT token, and basic user info.

Response Format:

{
        "message": "Login successful",
        "access_token": access_token,
        "user": {
            "id": user.user_id,
            "username": user.username,
            "firstname": user.firstname,
            "lastname": user.lastname,
            "likes": user.likes,
            "dislikes": user.dislikes
        }
    }

Edit User Info

Allows authenticated users to update specific personal information fields such as first name, last name, likes, and dislikes.

Endpoint: POST /edit_user

Authorization: Requires valid JWT token in header

Authorization: Bearer <access_token>

Key Container Description
firstname JSON User’s first name
lastname JSON User’s last name
likes JSON Updated user travel likes/preferences
dislikes JSON Updated user travel dislikes/preferences

Response: Returns updated user information and confirmation message.

Response Format:

{
        "message": "User updated successfully",
        "user": {
            "id": user.user_id,
            "username": user.username,
            "firstname": user.firstname,
            "lastname": user.lastname,
            "likes": user.likes,
            "dislikes": user.dislikes
        }
    }

FRIENDSHIP ENDPOINTS

Get Friends

Retrieves a list of user IDs for all confirmed friends of the specified user.

Endpoint: GET /get_friends/<user_id>

Authorization: Requires JWT token

Response: Array of user ID strings

Example Response:

["user123", "user456", "user789"]

Get Requests

Fetch all incoming friend requests for specified user

Endpoint: GET /get_invites/<user_id>

Response: Array of user ID strings

Example Response:

["user123", "user456", "user789"]

Get Users' Relationship

Endpoint: GET /get_relationship/<user_id1>/<user_id2>

Response: JSON of status dict between users

Example Response:

{"status": "friends"}

Send Friend Request

Allows the authenticated user to send a friend request to another user.

Endpoint: POST /send_friend_request/<user_id>

Authorization: Requires JWT token

Key Container Description
user_id JSON The user ID of the person to send a friend request to

Response: Returns a confirmation message when the request is successfully sent.

Accept Friend Request

Accepts a pending friend request from another user.

Endpoint: POST /friends/accept

Authorization: Requires JWT token

Key Container Description
user_id JSON The user ID of the person whose friend request is being accepted

Response: Returns confirmation that the friend request was accepted and relationship updated.

Decline Friend Request

Allows the user to decline an incoming friend request.

Endpoint: POST /friends/decline

Authorization: Requires JWT token

Key Container Description
user_id JSON The user ID of the person whose request is being declined

Response: Returns confirmation message that the request was declined.

Revoke Friend Request

Revoke a sent friend request

Endpoint: 'POST /revoke_friend_request/<user_id>'

Authorization: JWT Token Required

Response:

{"error": "No pending friend request found"}

Remove Friend

Remove an existing friend from friends list

Endpoint: 'POST /remove_friend/<user_id>'

Authorization: JWT Token Required

Response:

{"message": "Friend removed successfully"}

Search for Users, for Add Friends feature

Performs a live/debounced username search to find other users by username. Used in the “Add Friends” page for type-ahead user search.

Endpoint: 'GET /search_friends'

Authorization: Requires JWT token

Key Container Description
q URL Partial or full username to search for

This is the URL parameter. The full url will hence be https://api_url/friends/search?q=username

Response: Returns a list of users with their friendship status (none, friends, pending_outgoing, pending_incoming).

Response Format:

[
         {
            "user_id": user.user_id,
            "username": user.username,
            "firstname": user.firstname,
            "lastname": user.lastname,
            "status": status
         },
         {
            "user_id": user.user_id,
            "username": user.username,
            "firstname": user.firstname,
            "lastname": user.lastname,
            "status": status
          },
         ...
]

TRIP ENDPOINTS

Create new Trip. (Send form to LLM)

This endpoint allows the user to generate AI-powered trip itineraries using Gemini LLM based on destination, trip-specific preferences, and user-level preferences. The LLM returns structured JSON trip data containing stops and activities.

Endpoint: POST /trips/create

Authorization: Requires JWT token

Key Container Description
destination JSON Primary destination for the trip
num_versions JSON Number of itinerary versions to generate (1-5)
likes JSON Trip-specific likes (override user-level preferences) (optional)
dislikes JSON Trip-specific dislikes (override user-level preferences) (optional)

Response: Returns structured AI-generated trip itineraries following the strict JSON schema.

Response Format: Look into backend/sample_genai_trip.txt file for the response format returned from the LLM.

Get Trip Info

This endpoint returns information stored within the DB record for the specified trip.

Endpoint: GET /trip/{trip_id}/info

Authorization: Requires JWT token

Key Type Description
trip_id URL The unique identifier of the trip

This is a URL Parameter. The full URL will hence be https://api_url/trip/3/info for trip_id == 3.

Response Example:

{
  "trip_id": 17,
  "owner_id": 5,
  "status": "archived",
  "driving_polyline": "{wr~FhiyuOeBriJ",
  "driving_polyline_timestamp": 1762019914,
}

CAMERA ENDPOINTS

Landmark Context

This endpoint allows the user to obtain context based on an image they take with their camera on the app intended for helping travelers identify and learn more about attractions and landmarks they encounter.

Endpoint: POST /landmark_context

Key Container Description
image multipart/form An image file taken by the user of a landmark they want context for.

Response: Returns a JSON object containing LLM response test describing the image's context.

Response Format:

{
        "context": "Generated context ..."
}

Expected 201 Status Code on success.

PARTY MANAGEMENT (Owner Controlled)

Invite Member to Trip

This endpoint allows the trip owner to invite a confirmed friend to join their trip. Ownership is verified through the JWT token — the user making the request must be the trip’s owner. Only confirmed friends can be invited.

Endpoint: POST /party/invite

Authorization: Requires JWT token

Key Container Description
friend_id JSON The ID of the friend to invite
trip_id JSON The trip ID for which the invitation is being sent

Response Example:

{
  "message": "User 42 invited to trip 17"
}

Remove Member from Trip

This endpoint allows the trip owner to remove an existing member from their trip. Ownership is verified automatically via the JWT token.

Endpoint: POST /party/remove

Authorization: Requires JWT token

Key Container Description
friend_id JSON The ID of the member to remove
trip_id JSON The trip ID from which to remove the member

Response Example:

{
  "message": "User 42 removed from trip 17",
  "removed_by": 5
}

View Party Members in a Trip

This endpoint allows any trip participant — owner or member — to view all participants in a specific trip. Access is restricted: users who are not part of the trip will receive a 403 error.

Endpoint: GET /party/{trip_id}

Authorization: Requires JWT token

Key Type Description
trip_id URL The unique identifier of the trip

This is a URL Parameter. The full URL will hence be https://api_url/party/3 for trip_id == 3.

Response Example:

{
  "trip_id": 17,
  "owner_id": 5,
  "members": [
    {
      "user_id": 5,
      "username": "Frank",
      "firstname": "Frank",
      "lastname": "asdf"
    },
    {
      "user_id": 42,
      "username": "charlie",
      "firstname": "Charlie",
      "lastname": "asdf"
    }
  ]
}

Third-Party APIs

Gemini Image Recognition

https://ai.google.dev/gemini-api/docs/image-understanding This endpoint allows for using the Gemini LLM to perform image recognition to facilitate landmark context from uploaded user images.

Endpoint: POST /v1beta/models/gemini-2.5-flash:generateContent

Request Parameters: | Key| Container | Description | |-----|-----|-----|-----| | model | JSON | The model to use for image recognition | | contents | JSONArray | the inputs to feed towards the Gemini model, including the image and queries |

OSRM Routing

This endpoint allows user to obtain routing information with a number of parameters to manage their trip. https://project-osrm.org/docs/v5.5.1/api/#nearest-service Endpoint: GET /route/v1/

Request Parameters:

Key Container Description
alternatives URL Boolean for searching for alternative routes is allowed
steps URL Boolean for returning steps for each route leg
annotations URL Boolean for returning metadata for each coordinate along route geometry
geometries URL Determine format of returned route, either polyline, polyline6, or geojson
overview URL Determines level of detail of overview geometry
continue_straight URL Option for making routes as direct as possible even if slower

OSRM Routing API

https://project-osrm.org/docs/v5.5.1/api/#route-service This endpoint allows us to receive a driving polyline between stops on a route. Polylines come in Google encoded format and are then decoded into LatLng pairs in the frontend.

Endpoint: GET https://routing.openstreetmap.de/routed-car/route/v1/driving/{coordinatesSubStr}?geometries=polyline6 where {coordinatesSubStr} is a semicolon-seperated list of longitude and latitude tuples. For example: {coordinatesSubStr} = -83.7269,42.2986;-83.7753,42.2825

Example request: https://routing.openstreetmap.de/routed-car/route/v1/driving/-83.7269,42.2986;-83.7753,42.2825?geometries=polyline6

Example response:

{
    "code": "Ok",
    "routes": [{
        "legs": [{
            "steps": [],
            "weight": 489.1,
            "summary": "",
            "duration": 489.1,
            "distance": 5072.5
        }],
        "weight_name": "routability",
        "geometry": "squtoAjhhu~CltIbbOr{CpbDpiAjo@tiCphGbtCtrI`xEpJya@xl`@unBrlO`[bL|l@taA",
        "weight": 489.1,
        "duration": 489.1,
        "distance": 5072.5
    }],
    "waypoints": [{
        "hint": "Yw_DhEJfpIYUAAAABAAAAHYAAAAIAQAAyY_MQbJpekAFiRRDnKSlQxQAAAAEAAAAdgAAAAgBAADJdQAAam0C-ypthQLMbQL76GyFAhYA7w0AAAAA",
        "location": [-83.726998, 42.298666],
        "name": "Plymouth Road",
        "distance": 10.91341369
    }, {
        "hint": "6YdkgC7YZIA7AAAAFwAAABEBAAAIAAAAVRYlQmNBfEG2wD1DHo-7QDsAAAAXAAAAEQEAAAgAAADJdQAAuLAB-1ouhQK8sAH7BC6FAgoAfwUAAAAA",
        "location": [-83.775304, 42.282586],
        "name": "Longman Lane",
        "distance": 9.558459137
    }]
}

From this response, we take routes[0]["geometry"] and store in trip database object to later be sent to the frontend whenever changes are made to the stops on that trip.

Google Places API Nearby Search (New)

https://developers.google.com/maps/documentation/places/web-service/nearby-search This endpoint allows us to receive information about a stop such as ratings, hours, price range, address, and a link to that stops Google Maps entry. The endpoint takes a latitude and longitude and searches in a circle of radius 50 meters and returns information about the top result within that circle. This endpoint is called whenever a stop is newly created, either in trip creation or later on.

Endpoint: GET https://places.googleapis.com/v1/places:searchNearby

Headers:

{
    "X-Goog-Api-Key": [MAPS_API_KEY as set in .env],
    "X-Goog-FieldMask": "places.rating,places.priceRange,places.currentOpeningHours,places.shortFormattedAddress,places.googleMapsUri",
    "Content-Type": "application/json; charset=UTF-8"
}

Request Data:

{
    "maxResultCount": 1,
    "locationRestriction": {
        "circle": {
            "center": {
                "latitude": [Stop latitude from DB],
                "longitude": [Stop longitude from DB],
            },
            "radius": 50.0
        }
    }
}

Example response:

"places": [
      {
        "currentOpeningHours": {
          "nextOpenTime": "2025-11-24T14:00:00Z",
          "openNow": false,
          "periods": [
            {}, // Not displayed for brevity
            ...
          ],
          "weekdayDescriptions": [
            "Monday: 9:00\u202fAM\u2009\u2013\u20094:00\u202fPM",
            ...
          ]
        },
        "priceRange": {
          "endPrice": {
            "currencyCode": "USD",
            "units": "20"
          },
          "startPrice": {
            "currencyCode": "USD",
            "units": "10"
          }
        },
        "googleMapsUri": "https://maps.google.com/?cid=15450195039452542620&g_mp=Cilnb29nbGUubWFwcy5wbGFjZXMudjEuUGxhY2VzLlNlYXJjaE5lYXJieRACGAQgAA",
        "rating": 4.4,
        "shortFormattedAddress": "2781 Packard St, Ann Arbor"
      }
    ]
  }

From this response, we take the following data and adapt it/store in the following attributes on the stop database object:

JSON Response Key Attribute in DB
["places"][0]["rating"] rating
["places"][0]["priceRange"]["startPrice"]["units"] priceRange
["places"][0]["priceRange"]["endPrice"]["units"] priceRange
["places"][0]["shortFormattedAddress"] address
All items of ["places"][0]["currentOpeningHours"]["weekdayDescriptions"] hours
["places"][0]["googleMapsUri"] googleMapsUri

Clone this wiki locally