AACsearch
Recommendations

Personalized

Per-user re-ranking driven by analytics history and segment membership. The right engine when you know who the user is.

GET /recommendations/personalized returns items ranked for one specific user, mixing their interaction history with the broader trending signal.

Two endpoints power this:

  • GET /recommendations/personalized — Fast path. Reads precomputed per-user vectors.
  • GET /recommendations/personalized-from-analytics — Slow path. Walks the user's recent events live; use for users without a precomputed vector.

The API picks the right one automatically based on whether the user has a precomputed vector. You always call personalized.

Request

GET /recommendations/personalized?indexId=<id>&userId=<id>&limit=10
Authorization: Bearer <api-key>
ParamTypeRequiredNotes
indexIdstringyesSource index.
userIdstringyesStable user identifier — session id, account id, or hashed email.
limitnumberno1–50, default 10.
filterBystringnoOptional facet constraint.
segmentstringnoOptional user segment ID.

Response

{
  "items": [
    { "id": "sku-9001", "score": 0.82, "data": { ... } }
  ],
  "userId": "u_abc",
  "engine": "personalized" | "personalized-from-analytics" | "trending",
  "coldStart": false
}

The engine field tells you which path served the request. "trending" means cold start (see below).

Cold start

When a user has < 5 events, personalization is statistically worse than trending. The API detects this and silently falls back. The response carries coldStart: true and engine: "trending" — you can branch your UI labelling on it.

Do not hide the rail when coldStart=true. The user sees something useful (trending). Hiding it hurts conversion for the entire cold-start cohort, which is sometimes 30–40% of homepage views.

Required signal

The userId must be the same string the analytics events use. Otherwise the engine has no history to draw on.

For anonymous visitors, generate a stable session id at first page load (cookie / localStorage) and use it as userId. AACsearch does not require it to be a real account id.

Latency

Pathp95 (Pro)
personalized (precomputed)120 ms
personalized-from-analytics200 ms
trending (cold start)40 ms

Configuration

GET /recommendations/personalization-config returns the active config. Key knobs:

  • historyWindow — How far back to look (default 30 days).
  • decay — Half-life for events (default 7 days).
  • model — Embedding model for re-ranking.

Tune via dashboard → Search → Recommendations → Settings, or PATCH /recommendations/personalization-config.

Code path

packages/api/modules/recommendations/procedures/personalized.ts + personalized-from-analytics.ts. Precomputed vectors are produced by a nightly batch job documented in packages/recommendations/.

On this page