Most-viewed products (windowed)
The store’s most-viewed products over a time window, ranked by view count. Powers a “Popular now” homepage shelf or a “N people viewed this” PDP badge.
Publishable-key accessible; available on every plan. Returns product ids + a score (the
view count in the window) — hydrate the product details from the Products API. Results are
cached briefly, so counts reflect near-real-time activity, not the live millisecond.
curl --request GET \
--url https://api.tybritelabs.com/v1/discovery/most-viewed \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.tybritelabs.com/v1/discovery/most-viewed"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.tybritelabs.com/v1/discovery/most-viewed', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.tybritelabs.com/v1/discovery/most-viewed",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.tybritelabs.com/v1/discovery/most-viewed"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.tybritelabs.com/v1/discovery/most-viewed")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tybritelabs.com/v1/discovery/most-viewed")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"metric": "most-viewed",
"window_hours": 720,
"backfilled": false,
"products": [
{
"product_id": "0186665f-f0a1-4c79-976a-919b5b1c2daa",
"score": 15
},
{
"product_id": "068aa59d-1adf-4685-adf5-9793b1ffb9c9",
"score": 10
},
{
"product_id": "0c498ac2-4b77-4b03-a9b8-dbd4661efa54",
"score": 8
}
]
}{
"error": {
"code": "invalid_request",
"message": "Invalid request parameters",
"details": "The 'email' field is required"
}
}{
"error": {
"code": "unauthorized",
"message": "Missing or invalid Authorization header"
}
}{
"error": {
"code": "rate_limited",
"message": "Too many requests for this API key. Please slow down and try again shortly.",
"remaining": 0,
"reset": 1706198400
}
}{
"error": {
"code": "server_error",
"message": "An unexpected error occurred"
}
}Authorizations
API Key Authentication
Use your API key in the Authorization header:
Authorization: Bearer tybrite_sk_live_YOUR_KEY
Key Types:
Secret Keys (Server-Side Only):
- Format:
tybrite_sk_live_*(production) ortybrite_sk_test_*(sandbox) - Full read/write access to all endpoints
- ⚠️ NEVER expose in client-side code or public repositories
- Required for: every write a shopper does not make for themselves, authentication, payment verification, AI recommendations
Publishable Keys (Client-Safe):
- Format:
tybrite_pk_live_*(production) ortybrite_pk_test_*(sandbox) - Catalogue reads, plus the actions a shopper takes for themselves
- ✅ Safe for client-side JavaScript, mobile apps, and public code
- Allowed for: browsing products, search, CMS content, pricing queries, cart and wishlist, reviews, storefront events, and the Agent API's quotes, cart drafts and checkout intents
Endpoint-Specific Requirements:
- Authentication endpoints (
/v1/auth/*): Secret key required - Payment verification (
POST /v1/payments/verify): Secret key required - AI Recommendations (
POST /v1/recommendations): Secret key required - Semantic Search (
POST /v1/search): Both key types allowed (read-only operation) - Shopper actions (cart, wishlist, reviews, storefront events, Agent API quotes, cart drafts and checkout intents): Both key types allowed
- All other write operations: Secret key required
- All read operations: Both key types allowed
Using a publishable key for restricted operations returns 403 Forbidden.
Query Parameters
The ranking window in hours. One of 1, 24, 168, 720. Defaults to 24.
1, 24, 168, 720 Max products to return (1–50).
1 <= x <= 50Response
Ranked most-viewed products for the window.
A windowed storefront discovery list — product ids ranked by the requested signal.
The discovery metric returned (most-viewed, most-added-to-cart, or best-converting).
"most-viewed"
The time window the ranking covers, in hours.
720
Whether any entry in products is padding rather than a measured signal.
A store with little or no activity in the window would otherwise return an empty or
one-item shelf, so the list is topped up from featured and recently-added products. Those
entries are real, purchasable products and are safe to display — but they were not ranked
by the requested metric, and their score is a ranking weight rather than a view count or
conversion ratio.
true is common on a new store or a short window; it is not an error. Label the shelf
generically ("Popular picks") or hide it, rather than presenting padding as the metric.
false
Show child attributes
Show child attributes
curl --request GET \
--url https://api.tybritelabs.com/v1/discovery/most-viewed \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.tybritelabs.com/v1/discovery/most-viewed"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.tybritelabs.com/v1/discovery/most-viewed', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.tybritelabs.com/v1/discovery/most-viewed",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.tybritelabs.com/v1/discovery/most-viewed"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.tybritelabs.com/v1/discovery/most-viewed")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tybritelabs.com/v1/discovery/most-viewed")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"metric": "most-viewed",
"window_hours": 720,
"backfilled": false,
"products": [
{
"product_id": "0186665f-f0a1-4c79-976a-919b5b1c2daa",
"score": 15
},
{
"product_id": "068aa59d-1adf-4685-adf5-9793b1ffb9c9",
"score": 10
},
{
"product_id": "0c498ac2-4b77-4b03-a9b8-dbd4661efa54",
"score": 8
}
]
}{
"error": {
"code": "invalid_request",
"message": "Invalid request parameters",
"details": "The 'email' field is required"
}
}{
"error": {
"code": "unauthorized",
"message": "Missing or invalid Authorization header"
}
}{
"error": {
"code": "rate_limited",
"message": "Too many requests for this API key. Please slow down and try again shortly.",
"remaining": 0,
"reset": 1706198400
}
}{
"error": {
"code": "server_error",
"message": "An unexpected error occurred"
}
}
