← All use cases
E-commerce & PricingCSSRegex

Etsy Shop New Listings Monitor

Get notified the moment a favorite Etsy seller posts a new listing - useful for collectors, resellers, and merch buyers tracking limited drops.

Verid Use Cases·4 min read

The scenario

There's an Etsy seller whose work sells out within an hour of posting. You've been refreshing their shop a few times a day for weeks, sometimes catching the drop, mostly missing it. You'd happily pay for an email that hit your inbox the second they list anything new.

The same pattern applies to resellers tracking limited-run printable shops, collectors watching vintage sellers, and merch buyers tracking small-batch makers.

The problem

Etsy doesn't expose a public per-shop new-listing feed that's easy to subscribe to. There's RSS in some places, push notifications in the mobile app, and an email digest - but none of them fire within a minute of the listing going live, and none let you write code against them. Browser-tab refreshing is the manual workaround, which scales to about two shops before it ruins your afternoon.

How Verid solves it

A shop's listings page is a stable HTML grid. Verid loads the page on a fast interval (every ten or fifteen minutes works well), pulls out the count of listings and the title of the most recent one, and fires when either changes. Two fields, one predicate, done.

You can layer in a regex predicate if you only care about listings matching a keyword - "ceramic" or "vintage" or "size 8" - and silence everything else.

Build the monitor

Extraction config

{
  "method": "css",
  "fields": {
    "listing_count": ".wt-text-caption.wt-text-gray",
    "latest_title": "li.shop-home-listings-grid-item:first-child h3",
    "latest_url": "li.shop-home-listings-grid-item:first-child a"
  }
}

If you want to match by keyword instead of by position, swap to regex against the page's raw HTML:

{
  "method": "regex",
  "fields": {
    "new_ceramic_listing": "<h3[^>]*>([^<]*ceramic[^<]*)</h3>"
  }
}

Predicate

{ "type": "field_changes", "field": "latest_title" }

A new listing pushes everything down one row, so the title in the first slot changes. That's a reliable "something new dropped" signal.

Create the monitor

curl:

curl -X POST https://api.verid.dev/v1/monitors \
  -H "Authorization: Bearer vrd_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Etsy - FavoriteSeller new listings",
    "url": "https://www.etsy.com/shop/FavoriteSeller",
    "schedule_interval_seconds": 600,
    "extract_config": {
      "method": "css",
      "fields": {
        "listing_count": ".wt-text-caption.wt-text-gray",
        "latest_title": "li.shop-home-listings-grid-item:first-child h3",
        "latest_url": "li.shop-home-listings-grid-item:first-child a"
      }
    },
    "diff_predicate": { "type": "field_changes", "field": "latest_title" },
    "deliveries": [
      { "type": "email", "to": "you@example.com" }
    ]
  }'

SDK:

import { VeridClient } from '@verid.dev/sdk';

const client = new VeridClient({ apiKey: 'vrd_your_api_key' });

await client.monitors.create({
  name: 'Etsy - FavoriteSeller new listings',
  url: 'https://www.etsy.com/shop/FavoriteSeller',
  schedule_interval_seconds: 600,
  extract_config: {
    method: 'css',
    fields: {
      listing_count: '.wt-text-caption.wt-text-gray',
      latest_title: 'li.shop-home-listings-grid-item:first-child h3',
      latest_url: 'li.shop-home-listings-grid-item:first-child a',
    },
  },
  diff_predicate: { type: 'field_changes', field: 'latest_title' },
  deliveries: [{ type: 'email', to: 'you@example.com' }],
});

What the webhook delivers

{
  "id": "del_01H...",
  "version": "2026-05-01",
  "monitor_id": "9b1c…",
  "fired_at": "2026-05-08T12:00:00Z",
  "diff": {
    "fields_changed": ["latest_title", "latest_url", "listing_count"],
    "before": {
      "listing_count": "247 sales",
      "latest_title": "Handmade Ceramic Mug - Sage",
      "latest_url": "https://www.etsy.com/listing/1234567890"
    },
    "after": {
      "listing_count": "247 sales",
      "latest_title": "Hand-Thrown Bowl Set - Cobalt",
      "latest_url": "https://www.etsy.com/listing/9876543210"
    }
  }
}

Click straight through to the new listing from your email or webhook handler.

Caveats & tips

  • Etsy paginates. This monitor only sees the first page. If a seller drops several listings in a batch you'll get one webhook covering the most recent - which is fine for "tell me when they posted something new," not so fine if you need every single new SKU. For that case, use the seller's RSS feed if available with the RSS feed new items pattern.
  • Selectors drift. Etsy renames CSS classes from time to time. If your monitor starts returning empty fields, open the page in DevTools and refresh the selectors - Verid will surface extraction errors on the run detail page.
  • Be polite with the interval. Ten minutes is plenty fast for Etsy drops. One-minute polling won't catch anything sooner and increases the chance of being temporarily rate-limited.

Related use cases

For Shopify-based stores, Shopify product stock & price is the closer fit. For Amazon, see Amazon product watch. For RSS-driven listings, see RSS feed new items.

Ship this monitor today

5 monitors free, no credit card. Set up takes about a minute.

Get started free