Skip to content

Pagination & caching

Anonymous catalog reads (GET /v1/products, /v1/products/{sku}, /v1/categories, /v1/tags) are built to be paginated, cached, and synced cheaply.

Pagination

Paginate the product list with page / page_size, and filter with q, category, tag, and - for AUTO_PARTS merchants - vehicle_id:

bash
curl -s "https://api.harmon.example/v1/products?page=2&page_size=20&category=brakes" \
  -H "Authorization: Bearer hk_test_pub_your_key_here"

ETag / If-None-Match

Responses carry a strong ETag and a Cache-Control: max-age header. Send the ETag back as If-None-Match to revalidate - an unchanged resource returns 304 Not Modified with no body, which doesn't count against your rate limit:

bash
# First request - capture the ETag from the response headers:
curl -s -D - "https://api.harmon.example/v1/products?page=1" \
  -H "Authorization: Bearer hk_test_pub_your_key_here"
# → ETag: "a1b2c3…"

# Revalidate - unchanged returns 304, no body:
curl -s -o /dev/null -w '%{http_code}\n' "https://api.harmon.example/v1/products?page=1" \
  -H "Authorization: Bearer hk_test_pub_your_key_here" \
  -H 'If-None-Match: "a1b2c3…"'
# → 304

updated_since - incremental sync

Pass updated_since=<ISO-8601> to fetch only products changed since your last sync. This is the efficient way to keep a local cache - or a headless storefront's search index - fresh between webhook deliveries, without re-listing the whole catalog:

bash
curl -s "https://api.harmon.example/v1/products?updated_since=2026-06-01T00:00:00Z" \
  -H "Authorization: Bearer hk_test_pub_your_key_here"

A typical sync loop: store the timestamp of your last successful pull, then on the next run pass it as updated_since and merge the returned deltas into your local copy.

Next steps

In the API Reference

  • GET /v1/products - see the limit/cursor params, the ETag response header, and updated_since

Built on the Harmon platform — the storefront API for merchants.