Overview

Monitoring endpoints let you track stores for daily change detection, walk the snapshot timeline, diff any two snapshots, and query per-product inventory history. All monitoring endpoints live under two prefixes: /api/shops (simple tracking CRUD) and /api/store-detail/:slug (rich per-store views).

Base URL: https://shopsniffer.com/api

Auth: Better Auth session. Monitoring is user-scoped — you see only the stores you track.

POST /shops Stable

Track a shop for automatic daily scans.

domainstringrequiredpath

Shopify store domain to track.

Track allbirds.com
bash
curl -X POST https://shopsniffer.com/api/shops \ -H "X-API-Key: ss_your_key_here" \ -H "Content-Type: application/json" \ -d '{"domain": "allbirds.com"}'
Tracked 200
json
{ "shop": { "slug": "allbirds-com", "domain": "allbirds.com", "scan_frequency": "weekly", "created_at": "2026-04-12T10:30:00Z" }, "message": "Shop is now being tracked"}

Errors: 400 missing domain, 401 unauthenticated, 409 already tracking.


GET /shops Stable

List your tracked shops with latest scan status.

Tracked shops 200
json
{ "shops": [ { "slug": "allbirds-com", "domain": "allbirds.com", "scan_frequency": "daily", "last_scan": "2026-04-12T12:00:00Z", "product_count": 156, "changes_since_last": 3 } ]}

DELETE /shops Stable

Stop tracking a shop. Body must include the domain.

bash
curl -X DELETE https://shopsniffer.com/api/shops \ -H "X-API-Key: ss_your_key_here" \ -H "Content-Type: application/json" \ -d '{"domain": "allbirds.com"}'

GET /store-detail/:slug Stable

Per-store overview with summary stats, trends versus the previous snapshot, and the 20 most recent changes.

slugstringrequiredpath

Store slug (e.g. allbirds-com).

Store detail 200
json
{ "store": { "slug": "allbirds-com", "domain": "allbirds.com", "scan_frequency": "daily", "is_tracked": true, "tracked_since": "2026-03-01T08:00:00Z" }, "summary": { "total_snapshots": 42, "latest_job": { "id": "latest-uuid", "product_count": 156, "collection_count": 24, "page_count": 18, "screenshot_key": "allbirds-com/latest-uuid/screenshot.png", "created_at": "2026-04-12T12:00:00Z" }, "previous_job": { "id": "prev-uuid", "product_count": 153, "created_at": "2026-04-11T12:00:00Z" }, "trends": { "products": { "current": 156, "previous": 153, "delta": 3 }, "collections": { "current": 24, "previous": 24, "delta": 0 }, "pages": { "current": 18, "previous": 18, "delta": 0 } }, "latest_changes": { "added": 3, "removed": 0, "updated": 5 }, "total_changes_all_time": 247 }, "recent_changes": []}

GET /store-detail/:slug/snapshots Stable

Paginated snapshot timeline for a tracked store.

slugstringrequiredpath
Store slug.
pageintegerpathdefault: 1
Page number.
limitintegerpathdefault: 20
Results per page (max 100).

Snapshot timeline 200
json
{ "snapshots": [ { "job_id": "latest-uuid", "status": "completed", "product_count": 156, "collection_count": 24, "page_count": 18, "screenshot_key": "allbirds-com/latest-uuid/screenshot.png", "created_at": "2026-04-12T12:00:00Z", "changes_count": 3 } ], "pagination": { "page": 1, "limit": 20, "total": 42 }}

GET /store-detail/:slug/changes Stable

Paginated changes feed — the full log of added/removed/updated items across all snapshots.

slugstringrequiredpath
Store slug.

item_typestringpath

Filter by item type.

pageintegerpathdefault: 1
Page number.
limitintegerpathdefault: 50
Results per page.

Changes feed 200
json
{ "changes": [ { "id": 1001, "job_id": "latest-uuid", "shopify_id": "7891011121", "item_type": "product", "changes": [ { "field": "price", "from": "98.00", "to": "108.00" } ], "created_at": "2026-04-12T12:00:00Z", "item_title": "Tree Runners", "item_handle": "mens-tree-runners" } ], "pagination": { "page": 1, "limit": 50, "total": 247 }}

GET /store-detail/:slug/compare Stable

Side-by-side diff of any two snapshots. Returns added, removed, and changed items (up to 500 of each) plus a summary by item type.

slugstringrequiredpath
Store slug.
jobAstringrequiredpath
Older job UUID (baseline).
jobBstringrequiredpath
Newer job UUID (target).

Diff two snapshots
bash
curl "https://shopsniffer.com/api/store-detail/allbirds-com/compare?jobA=old-uuid&jobB=new-uuid" \ -H "Cookie: better-auth.session_token=…"
Diff 200
json
{ "jobA": { "id": "old-uuid", "product_count": 153, "collection_count": 24, "page_count": 18, "created_at": "2026-04-11T12:00:00Z" }, "jobB": { "id": "new-uuid", "product_count": 156, "collection_count": 24, "page_count": 18, "created_at": "2026-04-12T12:00:00Z" }, "diff": { "summary": { "products_added": 3, "products_removed": 0, "products_changed": 5, "collections_added": 0, "collections_removed": 0, "pages_added": 0, "pages_removed": 0 }, "added": [], "removed": [], "changed": [] }}
json
{ "error": "One or both jobs not found" }

PATCH /store-detail/:slug/frequency Stable

Update how often a tracked store is automatically scanned. Per-user preference; the effective frequency is the most frequent across all subscribers.

slugstringrequiredpath
Store slug.

frequencystringrequiredpath

Scan cadence for your subscription to this store.

Set daily monitoring
bash
curl -X PATCH https://shopsniffer.com/api/store-detail/allbirds-com/frequency \ -H "Cookie: better-auth.session_token=…" \ -H "Content-Type: application/json" \ -d '{"frequency": "daily"}'
Frequency updated 200
json
{ "success": true, "frequency": "daily", "effective_frequency": "daily"}

effective_frequency is the most aggressive cadence among all users tracking this store. If any user sets daily, the store is scanned daily and all subscribers get the update.


GET /store-detail/:slug/analytics Stable

Snapshot series plus a 365-day daily-changes heatmap for dashboard visualizations.

Analytics 200
json
{ "snapshot_series": [ { "job_id": "uuid", "product_count": 156, "collection_count": 24, "page_count": 18, "changes_count": 3, "created_at": "2026-04-12T12:00:00Z" } ], "daily_changes": [ { "date": "2026-04-12", "count": 3 }, { "date": "2026-04-11", "count": 1 } ]}

snapshot_series returns the last 100 completed snapshots in chronological order. daily_changes groups all changes in the last 365 days by date — ready to feed into a calendar heatmap.


GET /store-detail/:slug/inventory Beta

Store-level inventory overview. Returns total inventory, estimated daily sales, top sellers, and recent restocks, plus a 20-snapshot inventory time series.

Inventory overview 200
json
{ "summary": { "total_inventory": 48210, "total_products_tracked": 156, "estimated_daily_sales": 42.5, "total_units_sold_30d": 1275, "total_restocks_30d": 18, "top_sellers": [ { "shopify_id": "7891011121", "title": "Tree Runners", "units_sold_30d": 212 } ], "recent_restocks": [ { "shopify_id": "7891011121", "title": "Tree Runners", "quantity": 500, "at": "2026-04-10T00:00:00Z" } ] }, "time_series": [ { "job_id": "uuid", "total_inventory": 48210, "product_count": 156, "created_at": "2026-04-12T12:00:00Z" } ]}

Inventory monitoring requires the store to expose variant inventory_quantity on its public product JSON. Stores that hide inventory report total_inventory: 0.


GET /store-detail/:slug/inventory/product/:shopifyId Beta

Per-product inventory history and events.

slugstringrequiredpath
Store slug.
shopifyIdstringrequiredpath
Shopify product ID.

Product inventory detail 200
json
{ "product": { "title": "Tree Runners", "handle": "mens-tree-runners", "vendor": "Allbirds", "product_type": "Shoes" }, "history": [ { "total_inventory": 320, "variant_count": 12, "variant_detail": [], "created_at": "2026-04-12T12:00:00Z" } ], "events": [ { "event_type": "sale", "quantity_change": -15, "old_total": 335, "new_total": 320, "days_between": 1, "daily_rate": 15, "variant_changes": [{ "variant_id": 43210987654, "delta": -15 }], "created_at": "2026-04-12T12:00:00Z" } ]}

GET /store-detail/:slug/inventory/events Beta

Paginated inventory events feed (sales and restocks across the whole store).

slugstringrequiredpath
Store slug.

typestringpath

Filter to a single event type.

pageintegerpathdefault: 1
Page number.
limitintegerpathdefault: 50
Results per page.

Events feed 200
json
{ "events": [ { "shopify_id": "7891011121", "title": "Tree Runners", "handle": "mens-tree-runners", "event_type": "sale", "quantity_change": -15, "old_total": 335, "new_total": 320, "days_between": 1, "daily_rate": 15, "variant_changes": [], "created_at": "2026-04-12T12:00:00Z" } ], "pagination": { "page": 1, "limit": 50, "total": 482 }}

Next steps

Monitor prices guide

Full walkthrough: track → configure frequency → webhook → react to changes.

Learn More
Monitoring workflows

Background cron schedule, retention, and what happens daily at 12:00 UTC.

Learn More
Webhooks

Async notifications when monitoring detects changes.

Learn More
Monitoring feature

Conceptual overview of store monitoring.

Learn More