Recommendations
Requires a license with the
recommendationsfeature. See pricing.
Recommendations learns from what signed-in readers do with your entries: what they view, like, share and bookmark. From that it answers three questions: which entries are similar to this one, which are trending, and what this reader should see next. Scores are recomputed when you ask, from the console or from your own scheduler.
How it works
Section titled “How it works”| Step | What happens |
|---|---|
| Record | Your front end reports each action a reader takes on an entry, with the reader's own token. |
| Recompute | A super admin runs a recompute. It pairs entries the same readers acted on in the last 30 days and ranks the last seven days' activity for trending. |
| Read | Your front end asks for similar entries, trending entries or the reader's feed, and gets entry ids back. Read the entries through the Content API to show them. |
Each action counts toward a reader's feed with its own weight:
| Action | Weight |
|---|---|
view | 1 |
like | 2 |
share | 3 |
bookmark | 5 |
Try it
Section titled “Try it”You need a token in TOKEN for a super_admin, which also counts as a reader here. The
quickstart shows how to get one. Put the ids of two
entries in A and B.
-
Record that you liked both entries:
Terminal window curl -X POST http://localhost:3002/api/v1/recommendations/behavior \-H "Authorization: Bearer $TOKEN" \-H "Content-Type: application/json" \-d "{\"content_id\": \"$A\", \"action\": \"like\"}"curl -X POST http://localhost:3002/api/v1/recommendations/behavior \-H "Authorization: Bearer $TOKEN" \-H "Content-Type: application/json" \-d "{\"content_id\": \"$B\", \"action\": \"like\"}"Each answers
201with the recordedid,user_id,content_id,actionandcreated_at. -
Recompute the scores:
Terminal window curl -X POST http://localhost:3001/api/admin/recommendations/refresh \-H "Authorization: Bearer $TOKEN"{ "similarity_pairs_computed": 1, "trending_items_computed": 2, "feeds_generated": 0, "duration_ms": 9 } -
Ask what is similar to the first entry:
Terminal window curl "http://localhost:3002/api/v1/recommendations/similar?content_id=$A&limit=5" \-H "Authorization: Bearer $TOKEN"{ "similar": ["<B>"] } -
Read the trending list:
Terminal window curl "http://localhost:3002/api/v1/recommendations/trending?limit=10" \-H "Authorization: Bearer $TOKEN"The answer is
{"items": [...]}, each withcontent_id,scoreandview_count. -
Open Settings, then Recommendations, in the admin console. Trending now lists both entries.
Record what readers do
Section titled “Record what readers do”POST /api/v1/recommendations/behavior takes content_id, an entry's id, and action, one of
view, like, share or bookmark. Send it with the reader's own token, so the action is
recorded against them. Any signed-in caller may record.
Show recommendations
Section titled “Show recommendations”Every route under /api/v1/recommendations needs a signed-in caller. Each answers entry ids.
| To show | Call | Answer |
|---|---|---|
| Entries similar to one entry | GET /api/v1/recommendations/similar?content_id=<id> | {"similar": ["<id>", ...]}. limit is 10 by default, at most 100. |
| What is trending | GET /api/v1/recommendations/trending | {"items": [{"content_id", "title", "slug", "score", "view_count"}]}, up to the top 100. limit is 20 by default. title and slug are empty, so read the entry for them. |
| The caller's feed | GET /api/v1/recommendations/feed | {"entries": [{"content_id", "score", "source", ...}], "total": n}. limit is 20 by default, at most 100, and offset at most 10000. |
Two entries are similar when the same readers acted on both in the last 30 days, with any
action, a view included. A feed entry's source
is similar, for an entry close to one the reader acted on, or collaborative, for one other
readers with the same taste liked. The feed is built when it is requested, from the scores of
the last recompute. A limit or offset above its maximum is lowered, not refused.
Recompute scores
Section titled “Recompute scores”Recompute after a batch of activity, or call the refresh route on a timetable from your own
tooling, signed in as a super admin. In the console, a super admin chooses
Recompute under Settings, then Recommendations. Only one recompute runs at a time,
and a second answers 409.
Show recommendations to half your readers
Section titled “Show recommendations to half your readers”Each reader is put in the recommendation group or the random group, at random, the first
time they call GET /api/v1/recommendations/ab-test, and stays there:
{ "bucket": "recommendation", "recommendation_pct": 50.4, "random_pct": 49.6, "total_users": 1250 }The group is a label your front end reads. LyEve serves the same answers to both groups, so
show recommendation blocks only to readers in recommendation, and compare how the two groups
engage. A reader who never calls ab-test is in neither group. GET /api/admin/recommendations/ab-stats returns recommendation_count, random_count,
total_users, recommendation_pct and random_pct.
Settings
Section titled “Settings”Recommendations have no settings of their own. If you set LYEVE_PLUGINS to choose which
features start, include recommendations in it. See
licensing and tiers.
Routes
Section titled “Routes”The admin routes take a signed-in session. An admin token cannot call them.
Recommendation routes
| Method | Path | Role | Purpose |
|---|---|---|---|
POST | /api/v1/recommendations/behavior | signed in | Record a view, like, share or bookmark. |
GET | /api/v1/recommendations/similar | signed in | Entries similar to content_id. |
GET | /api/v1/recommendations/trending | signed in | Trending entries. |
GET | /api/v1/recommendations/feed | signed in | The caller's feed. |
GET | /api/v1/recommendations/ab-test | signed in | The caller's group and the split. |
GET | /api/admin/recommendations/ab-stats | admin | Group counts and percentages. |
POST | /api/admin/recommendations/refresh | super_admin | Recompute every score. |
POST | /api/admin/recommendations/generate-feed/{userID} | super_admin | Build and return one user's feed. |
Errors
Section titled “Errors”Without a license that carries recommendations, the routes answer 404. A license that lapses
while the instance runs makes them answer 402 payment_required.
Every error these routes return
| Status | Message | Cause |
|---|---|---|
400 | content_id is required, action is required | A field is missing. |
400 | invalid action | The action is not view, like, share or bookmark. |
400 | invalid JSON body | The body is not JSON, or content_id is not a UUID on behavior. |
400 | invalid content_id | content_id is not a UUID on similar. |
400 | invalid user ID | The id in generate-feed is not a UUID. |
401 | authentication required | The caller is not signed in. |
402 | payment_required | The license lapsed while the instance ran. |
409 | a refresh is already in progress | A recompute is still running. |
503 | recommendations is not available | The feature is not ready. |
Related
Section titled “Related”- A/B testing: test your own variants and measure conversions.
- Analytics: views and visitors.
- Content lifecycle: the entries recommendations point at.