Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/viet2811/uk-travel-recommendation/llms.txt

Use this file to discover all available pages before exploring further.

This endpoint populates the authenticated user’s recommendation profile with their attraction type preferences and a set of free-text interest labels. It accepts two pieces of data: a 9-element binary array (preferences) that encodes which broad attraction categories the user is interested in, and a list of human-readable label strings (labels) that describe their interests in natural language. Internally, the labels are encoded into a dense 384-dimensional vector using the all-MiniLM-L12-v2 sentence-transformer model and stored as labelEmbed and summaryEmbed on the user’s UserProfile. The preferences array is stored directly as labelMHE. Until this endpoint is called, all three vectors remain at zero (as set during registration), and the recommendation engine will return generic results. Bearer token authentication is required.

Endpoint

MethodPOST
Path/api/user/preferences/
Auth requiredYes — Authorization: Bearer <access_token>
Content-Typeapplication/json

Request Body

preferences
integer[]
required
A fixed-length array of exactly 9 integers. Each element must be either 0 (not interested) or 1 (interested), corresponding to one of the 9 UK attraction category groups. The array is stored directly as the labelMHE field on the user’s profile and is used as a multi-hot encoding of category interest.
labels
string[]
required
An array of human-readable strings describing the user’s interests. Each string is encoded individually by the all-MiniLM-L12-v2 sentence-transformer, and the resulting embeddings are averaged into a single 384-dimensional vector. That vector is stored as both labelEmbed and summaryEmbed on the user’s UserProfile and is used for semantic similarity matching during recommendation retrieval. If the array is empty, labelEmbed and summaryEmbed are left unchanged and only labelMHE is updated. More descriptive, specific labels yield more precise semantic embeddings.Example values: "historic castle", "coastal walk", "national park", "contemporary art museum".

Responses

200 OK

Returned when both fields pass validation and the UserProfile is updated successfully. The response body is empty.
200 OK
HTTP/1.1 200 OK
Content-Length: 0

400 Bad Request

Three distinct validation errors can be returned:
error
string
A message describing the validation failure. One of the three values below.

401 Unauthorized

Returned when the Authorization header is absent, the access token is missing, or the token has expired. Obtain a fresh token via Refresh Token or Login.
401 Unauthorized
{
  "detail": "Authentication credentials were not provided."
}
Call this endpoint during onboarding — before the user makes their first recommendation fetch. The recommendation engine computes similarity between the user’s labelEmbed / summaryEmbed vectors and attraction description embeddings; zero vectors produce meaningless similarity scores. More descriptive labels (e.g. "ruined medieval fortification" rather than just "castle") produce richer semantic embeddings and noticeably improve recommendation quality.

How the embedding works

When a valid request is received, the backend performs the following steps:
  1. Validates preferences (list, length 9) and labels (list).
  2. Passes labels to the pre-loaded all-MiniLM-L12-v2 sentence-transformer model.
  3. Encodes each label individually, then averages the embeddings (np.mean(embeddings, axis=0)) into a single 384-dimensional vector.
  4. Persists the update to the authenticated user’s UserProfile:
FieldValue stored
labelMHEThe 9-element preferences array as provided
labelEmbedThe 384-dim sentence-transformer embedding of labels
summaryEmbedThe same 384-dim embedding (used in a separate similarity pass)

Example request

{
  "preferences": [1, 0, 1, 1, 0, 0, 1, 0, 1],
  "labels": ["historic castle", "museum", "national park", "coastal walk"]
}
In this example the user has toggled on positions 0 (historic sites), 2 (national parks), 3 (coastal walks), 6 (food & drink), and 8 (family attractions). The four label strings will be encoded together into a single semantic vector that captures the combined meaning of those interests.

Full examples

curl --request POST \
  --url http://localhost:8000/api/user/preferences/ \
  --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' \
  --header 'Content-Type: application/json' \
  --data '{
    "preferences": [1, 0, 1, 1, 0, 0, 1, 0, 1],
    "labels": ["historic castle", "museum", "national park", "coastal walk"]
  }'

Build docs developers (and LLMs) love