> ## Documentation Index
> Fetch the complete documentation index at: https://docs.shopsniffer.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Monitoring API

Track shops for change detection, view snapshot history, compare two snapshots, and query inventory events and analytics.

## 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.

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**

```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**

```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.

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

**Store detail**

```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.

Store slug.
Page number.
Results per page (max 100).

**Snapshot timeline**

```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.

Store slug.
Filter by item type.
Page number.
Results per page.

**Changes feed**

```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.

Store slug.
Older job UUID (baseline).
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**

```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 title="404 Not Found"
{ "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.

Store slug.
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**

```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**

```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**

```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.

Store slug.
Shopify product ID.

**Product inventory detail**

```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).

Store slug.
Filter to a single event type.
Page number.
Results per page.

**Events feed**

```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](/guides/monitor-prices)**

Full walkthrough: track → configure frequency → webhook → react to changes.
  **[Monitoring workflows](/monitoring-workflows)**

Background cron schedule, retention, and what happens daily at 12:00 UTC.
  **[Webhooks](/webhooks)**

Async notifications when monitoring detects changes.
  **[Monitoring feature](/monitoring)**

Conceptual overview of store monitoring.