← Blog

Vinted

Vinted Alerts: Build a Bot for New Listing Notifications

Get Vinted notifications for new listings on Telegram, Discord or email: a scheduled Apify search plus a short Python bot that only alerts on unseen IDs.

Epic Scrapers

Vinted’s saved searches live inside the app: you can’t route them to a team channel, check them on your own schedule, or add your own rules. If you hunt deals or source stock, you want a Vinted bot that checks your exact search every few minutes and pings you on Telegram, Discord or email the moment something new shows up.

This tutorial builds one with three pieces: the Vinted Scraper running your search on a schedule, its built-in “new listings only” mode, and either a no-code integration or a short Python script that sends the notification and never alerts on the same listing twice.

Step 1: Build the exact search on Vinted

Open Vinted and set every filter you care about: brand, size, condition, category, max price. Then sort by Newest first, since new listings appear at the top and a small result limit is enough. Copy the URL from your browser.

https://www.vinted.fr/catalog?search_text=carhartt%20jacket&price_to=60&order=newest_first

A filtered URL beats a plain keyword for alerts because it keeps all of Vinted’s filters. If a keyword and a price range are enough, use keywords, country, minPrice and maxPrice instead.

Step 2: Turn on “new listings only”

The scraper remembers listings between runs of the same search. Set Save only (saveOnly) to new and each run saves only listings it hasn’t seen before. Use newOrPriceDrops if you also want an alert when a listing you already saw gets cheaper.

{
  "startUrls": [
    { "url": "https://www.vinted.fr/catalog?search_text=carhartt%20jacket&price_to=60&order=newest_first" }
  ],
  "maxProducts": 50,
  "saveOnly": "new"
}

The first run for a search saves everything it finds as a baseline. Ignore that run’s results (the script below does this for you), and from the second run on you only get fresh listings.

maxProducts controls how many of the newest listings each run checks. Set it a bit above the number of new items a search gets between runs: 20 to 50 is plenty for most niche searches checked every 15 minutes.

Click Save as a new task. A task is a saved input you can schedule and call by ID.

Step 3: Schedule the task

In Apify Console, open Schedules, click Create new, add your task, and pick a frequency:

Search Frequency Cron
Popular, underpriced items Every 10 min */10 * * * *
Specific brand + size Every hour 0 * * * *
Broad category watch Every 6 hours 0 */6 * * *

Every run costs a small amount, so start hourly and tighten it only for searches where speed actually matters. You can add several tasks to the same schedule.

Step 4a: No-code notifications

The quickest route needs no code. In your task’s Integrations tab you can connect email, Slack, Make, Zapier, n8n or a webhook. Because saveOnly is new, each run’s dataset already contains only new listings, so the integration just forwards them.

For Telegram or Discord via n8n:

  1. In n8n, add a Webhook trigger and copy its URL.
  2. In the Apify task, add a webhook integration on the Run succeeded event pointing to that URL. The payload includes resource.defaultDatasetId.
  3. Add an HTTP Request node that calls https://api.apify.com/v2/datasets/{{$json.body.resource.defaultDatasetId}}/items with your Apify token.
  4. Add a Telegram or Discord node that sends title, price.amount, price.currency_code and url for each item.

Make and Zapier work the same way with their Apify apps: trigger on a finished task run, fetch the dataset items, send a message per item.

Step 4b: A Python Vinted bot with ID dedupe

If you’d rather own the logic, this script reads the latest successful run of your task, skips any listing ID it has already sent, and posts the rest to Telegram and/or Discord. Deduping by id matters for two reasons: overlapping searches in one run can return the same listing twice, and if the script runs twice against the same run you don’t want double alerts.

import json, os, pathlib, requests
from apify_client import ApifyClient

TASK_ID = os.environ["APIFY_TASK_ID"]          # e.g. "yourname~vinted-carhartt"
SEEN_FILE = pathlib.Path("seen_ids.json")
TG_TOKEN = os.environ.get("TELEGRAM_BOT_TOKEN")
TG_CHAT = os.environ.get("TELEGRAM_CHAT_ID")
DISCORD_URL = os.environ.get("DISCORD_WEBHOOK_URL")

def notify(text):
    if TG_TOKEN and TG_CHAT:
        requests.post(f"https://api.telegram.org/bot{TG_TOKEN}/sendMessage",
                      json={"chat_id": TG_CHAT, "text": text}, timeout=10)
    if DISCORD_URL:
        requests.post(DISCORD_URL, json={"content": text}, timeout=10)

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.task(TASK_ID).last_run(status="SUCCEEDED")
items = list(run.dataset().iterate_items())

first_time = not SEEN_FILE.exists()
seen = set() if first_time else set(json.loads(SEEN_FILE.read_text()))

for item in items:
    listing_id = str(item["id"])
    if listing_id in seen:
        continue
    seen.add(listing_id)
    if first_time:
        continue  # baseline: remember, don't alert
    price = item.get("price") or {}
    label = "Price drop" if item.get("price_dropped") else "New"
    notify(f"{label}: {item['title']}\n"
           f"{price.get('amount')} {price.get('currency_code')}"
           f" | {item.get('brand_title') or ''} {item.get('size_title') or ''}"
           f" | {item.get('status') or ''}\n{item['url']}")

SEEN_FILE.write_text(json.dumps(sorted(seen)))
print(f"{len(items)} items in run, {len(seen)} IDs remembered")

Install the dependencies with pip install apify-client requests, set APIFY_TOKEN and the other variables, and run it from cron a minute or two after each scheduled Apify run. To get a Telegram token, message @BotFather and create a bot. For Discord, create a webhook under the channel’s Integrations settings.

If you want price drops too, set saveOnly to newOrPriceDrops. A price drop keeps the same id, so key the seen set on f"{item['id']}:{price.get('amount')}" instead, and a cheaper price for a known listing will alert once.

Want to run it without a server? Swap the cron trigger for an Apify webhook pointed at a small serverless function (Cloudflare Workers, AWS Lambda, Vercel) and keep the seen IDs in a key-value store or a database row instead of a local file.

Add your own rules before alerting

Vinted’s filters handle brand, size and price. For anything fuzzier, either filter in the script (for example, skip business sellers with item["user"]["business"], or alert only below a price) or let the scraper do it with the AI filter:

{
  "startUrls": [
    { "url": "https://www.vinted.de/catalog?search_text=thinkpad&order=newest_first" }
  ],
  "maxProducts": 30,
  "saveOnly": "new",
  "aiFilteringEnabled": true,
  "aiFilterPrompt": "Only working ThinkPads with at least 16 GB RAM. Exclude listings for parts or with a broken screen.",
  "aiMatchThreshold": "0.7"
}

Only matching new listings reach the dataset, so your bot stays quiet until there’s something worth opening.

Tips for a reliable Vinted bot

  • One task per search. Price tracking history is stored per search URL, so separate tasks keep alerts clean and easy to pause.
  • Watch the run count, not just alerts. A run with nothing new saves nothing, which is normal. If a search is silent for days, open it on Vinted to check the filters still match.
  • Watch several countries. Add compareCountries to a keyword search to alert on the same item across Vinted sites. Each listing carries vinted_country.

FAQ

Is there an official Vinted notification API?

No. Vinted has in-app saved-search notifications but no public API for them. A scheduled scraper is the usual way to build custom alerts.

How fast are the alerts?

As fast as your schedule. A 10-minute schedule means a new listing reaches you within about 10 minutes plus run time.

Can the bot buy items or message sellers automatically?

No, and you shouldn’t try. The scraper only reads public listings. You open the link and decide.

Why did the first run send nothing?

That’s the baseline. The first run of a search has nothing to compare against, so the script remembers the IDs without alerting.

Set up your first alert

Build one newest-first search on Vinted, paste it into the Vinted Scraper with saveOnly set to new, save it as a task and schedule it. To track how prices move over time rather than only catching new items, read Vinted price tracking. For the full field list and search options, see the Vinted scraper guide.