Product price tracking
Your products on Google Shopping and Amazon: on the shelf or not, position, the cheapest comparable listing and how far above it you are.
Product price tracking: plan and usage
GET/api/v1/product-trackingScope products:read
Your plan, how many products it covers and how your products are doing on the shelves.
Example
curl -s "https://app.pbn.ltd/api/v1/product-tracking" \
-H "Authorization: Bearer $PBN_API_KEY"
import os
import requests
headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.get("https://app.pbn.ltd/api/v1/product-tracking", headers=headers, timeout=120)
print(r.status_code, r.json())
const res = await fetch("https://app.pbn.ltd/api/v1/product-tracking", {
method: "GET",
headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());
Response
200
{
"data": {
"plan": "Product price tracking + 1 x +25 products",
"unlimited": false,
"paid_until": "2026-10-25",
"products": 12,
"products_included": 35,
"listed": 9,
"not_listed": 3,
"undercut": 2,
"price_from": "15.00"
}
}
Errors: rate_limited, scope_missing, unauthorized
List your tracked products
GET/api/v1/product-tracking/productsScope products:read
Every product you track, with the latest reading of each shelf.
Example
curl -s "https://app.pbn.ltd/api/v1/product-tracking/products" \
-H "Authorization: Bearer $PBN_API_KEY"
import os
import requests
headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.get("https://app.pbn.ltd/api/v1/product-tracking/products", headers=headers, timeout=120)
print(r.status_code, r.json())
const res = await fetch("https://app.pbn.ltd/api/v1/product-tracking/products", {
method: "GET",
headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());
Response
200
{
"data": [
{
"id": 41,
"title": "Sony WH-1000XM5",
"country": "GB",
"asin": "B09Y2MYL5C",
"sku": "WH1000XM5B",
"competitor": false,
"covered_by_plan": true,
"shelves": [
{
"shelf": "google",
"state": "ok",
"listed": true,
"position": 3,
"your_price": "229.00",
"cheapest_price": "199.99",
"cheapest_seller": "Argos",
"currency": "GBP",
"gap_percent": "14.51",
"listings": 20,
"comparable": 12,
"last_read_at": "2026-09-26T11:40:00Z"
}
]
}
]
}
Errors: rate_limited, scope_missing, unauthorized
One product
GET/api/v1/product-tracking/products/{product_id}Scope products:read
One product with every listing we read on each shelf ("counted" = comparable to your product; "yours" = recognised by your seller name or ASIN).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
product_id | path | integer | yes | The product id. |
Example
curl -s "https://app.pbn.ltd/api/v1/product-tracking/products/product_id" \
-H "Authorization: Bearer $PBN_API_KEY"
import os
import requests
headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.get("https://app.pbn.ltd/api/v1/product-tracking/products/product_id", headers=headers, timeout=120)
print(r.status_code, r.json())
const res = await fetch("https://app.pbn.ltd/api/v1/product-tracking/products/product_id", {
method: "GET",
headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());
Response
200
{
"data": {
"id": 41,
"title": "Sony WH-1000XM5",
"country": "GB",
"asin": "B09Y2MYL5C",
"sku": "WH1000XM5B",
"competitor": false,
"covered_by_plan": true,
"shelves": [
{
"shelf": "google",
"state": "ok",
"listed": true,
"position": 3,
"your_price": "229.00",
"cheapest_price": "199.99",
"cheapest_seller": "Argos",
"currency": "GBP",
"gap_percent": "14.51",
"listings": 20,
"comparable": 12,
"last_read_at": "2026-09-26T11:40:00Z"
}
],
"listings": {
"google": [
{
"position": 1,
"title": "Sony WH-1000XM5 Wireless",
"seller": "Argos",
"price": "199.99",
"currency": "GBP",
"yours": false,
"counted": true,
"cheapest": true
}
]
}
}
}
Errors: not_found, rate_limited, scope_missing, unauthorized
Track a product
POST/api/v1/product-tracking/productsScope products:write
Adds a product and reads both shelves at once. Refused before anything is spent if your plan has no room.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
title | body | string | yes | The product the way shoppers search for it, e.g. "Sony WH-1000XM5". |
country | body | string (one of: GB, US, DE, FR, ES, IT, CA, AU) | yes | The country you sell it in (the list is kept by us and may grow). |
asin | body | string | no | Your Amazon ASIN for it, to recognise your listing. |
sku | body | string | no | Your SKU or GTIN (for your own reference). |
competitor | body | boolean | no | True for a competitor's product (watched, never "yours"). Default: False. |
Example
curl -s -X POST "https://app.pbn.ltd/api/v1/product-tracking/products" \
-H "Authorization: Bearer $PBN_API_KEY"
import os
import requests
headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.post("https://app.pbn.ltd/api/v1/product-tracking/products", headers=headers, timeout=120)
print(r.status_code, r.json())
const res = await fetch("https://app.pbn.ltd/api/v1/product-tracking/products", {
method: "POST",
headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());
Response
201
{
"data": {
"id": 41,
"title": "Sony WH-1000XM5",
"country": "GB",
"asin": "B09Y2MYL5C",
"sku": "WH1000XM5B",
"competitor": false,
"covered_by_plan": true,
"shelves": [
{
"shelf": "google",
"state": "ok",
"listed": true,
"position": 3,
"your_price": "229.00",
"cheapest_price": "199.99",
"cheapest_seller": "Argos",
"currency": "GBP",
"gap_percent": "14.51",
"listings": 20,
"comparable": 12,
"last_read_at": "2026-09-26T11:40:00Z"
}
]
}
}
Errors: payment_required, rate_limited, scope_missing, unauthorized, validation_failed
Stop tracking a product
DELETE/api/v1/product-tracking/products/{product_id}Scope products:write
Removes the product and its history.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
product_id | path | integer | yes | The product id. |
Example
curl -s -X DELETE "https://app.pbn.ltd/api/v1/product-tracking/products/product_id" \
-H "Authorization: Bearer $PBN_API_KEY"
import os
import requests
headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.delete("https://app.pbn.ltd/api/v1/product-tracking/products/product_id", headers=headers, timeout=120)
print(r.status_code, r.json())
const res = await fetch("https://app.pbn.ltd/api/v1/product-tracking/products/product_id", {
method: "DELETE",
headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());
Response
200
{
"data": {
"deleted": true
}
}
Errors: not_found, rate_limited, scope_missing, unauthorized