Closetta exposes a public REST API with live and historical Canadian fashion sale data. If you want to build something on top of it — a Slack bot, an email digest, a personal deal monitor — here's a working example in Python.
What the API Provides
The Closetta public API (no auth required) has four endpoints:
GET /api/v1/brands— all tracked brands with current sale statusGET /api/v1/sales— currently active sales with discount depthsGET /api/v1/brand-history?brand=gap— month-by-month discount history for a brandGET /api/v1/trends— brands trending up or down in discount depth
Full API documentation: closetta.com/api
The Goal
We'll build a script that:
- Fetches all active sales from
/api/v1/sales - Filters for brands where the discount is at or above a threshold you set
- Sends a Slack message (or prints to console) with the matching deals
This runs on a schedule (cron, GitHub Actions, whatever you use) and posts only when new deals cross your threshold.
The Code
import requests
import json
from datetime import date
CLOSETTA_BASE = "https://closetta.com/api/v1"
SLACK_WEBHOOK = "https://hooks.slack.com/services/YOUR/WEBHOOK/HERE" # optional
MIN_DISCOUNT = 50 # only alert on 50%+ deals
def get_active_sales():
response = requests.get(f"{CLOSETTA_BASE}/sales")
response.raise_for_status()
return response.json()
def filter_deals(sales, min_discount):
return [
s for s in sales
if s.get("discountPercent", 0) >= min_discount
]
def format_message(deals):
if not deals:
return None
lines = [f"*Closetta Deal Alert — {date.today()}*"]
for deal in sorted(deals, key=lambda d: d["discountPercent"], reverse=True):
brand = deal["brand"]
pct = deal["discountPercent"]
label = deal.get("saleLabel", "on sale")
lines.append(f"• *{brand}* — {pct}% off ({label})")
return "\n".join(lines)
def post_to_slack(message, webhook_url):
payload = {"text": message}
requests.post(webhook_url, data=json.dumps(payload))
def main():
sales = get_active_sales()
deals = filter_deals(sales, MIN_DISCOUNT)
message = format_message(deals)
if message:
if SLACK_WEBHOOK:
post_to_slack(message, SLACK_WEBHOOK)
else:
print(message)
else:
print(f"No deals above {MIN_DISCOUNT}% today.")
if __name__ == "__main__":
main()
That's it. Under 40 lines including imports and the Slack integration.
Variations
Email instead of Slack: Replace post_to_slack with Python's smtplib or an API like Resend/Mailgun. The message format works for both.
Only alert on new deals: Store the previous day's matching brands in a file or database, and only post when a brand appears that wasn't there yesterday.
Per-brand threshold: Instead of a global MIN_DISCOUNT, use a dict:
BRAND_THRESHOLDS = {
"lululemon": 30,
"marc-jacobs": 40,
"the-north-face": 50,
}
Then filter filter_deals against the brand-specific threshold instead of the global one.
Track historical context: Add a call to /api/v1/brand-history for each deal to include whether the current discount is above or below the brand's historical average:
def get_history(brand_slug):
r = requests.get(f"{CLOSETTA_BASE}/brand-history", params={"brand": brand_slug})
if r.ok:
return r.json()
return []
Running on a Schedule
The simplest setup: a GitHub Actions cron job.
# .github/workflows/deal-alert.yml
name: Daily Deal Alert
on:
schedule:
- cron: '0 9 * * *' # 9am UTC daily
jobs:
alert:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.11'
- run: pip install requests
- run: python deal_alert.py
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
No server required. Free tier GitHub Actions handles this comfortably.
Using the MCP Server Instead
If you're building with an AI agent (Claude, GPT, etc.) rather than a standalone script, the Closetta MCP server gives your agent live access to the same data through natural language queries. The REST API is better for scheduled scripts; the MCP server is better for interactive agents.
The Closetta public API is free to use. Rate limits apply — see closetta.com/api for current limits. API schema may evolve; check the docs for the latest response format.