Changelog
Every shipped release — in reverse-chronological order. No marketing. Just code.
Drop-in Middleware — @filtrate/express, @filtrate/fastify, @filtrate/next
- @filtrate/express: Express middleware that intercepts multipart uploads, scans via /v1/process, and exposes results on req.filtrate — blocked uploads never reach your handler
- @filtrate/fastify: Fastify plugin equivalent; register once, get request.filtrate in every route handler
- @filtrate/next: withFiltrate() wrapper for App Router Route Handlers + withFiltratePages() for Pages API — TypeScript-first, zero config beyond FILTRATE_API_KEY
- All packages: configurable block verdicts, onBlock callback, timeout, async mode, full TypeScript types, MIT licensed
- Homepage hero: tabbed "Drop in. One line." code snippet rotating through Express / Fastify / Next.js
- /docs#middleware: new section with install commands, usage examples, options table, and req.filtrate shape docs
Public Changelog + RSS Feed
- New /changelog page showing product velocity — reverse-chronological release log with version tags
- RSS 2.0 feed at /changelog.rss for developers to subscribe without a newsletter
- Subscribe-by-email capture at the bottom — stores to changelog_subscribers table, Postmark-backed confirm
- JSON-LD Article + ItemList schema for every entry; IndexNow ping + sitemap update
/benchmarks — Head-to-Head Comparison
- New /benchmarks page with live data: latency, accuracy, compression ratio, cost across 4 providers
- Benchmark harness at scripts/benchmark.js — 100-image test set, live mode via FILTRATE_BENCHMARK_API_KEY
- Bar chart, feature table, per-provider takeaways, methodology section, and CTA
- JSON-LD Dataset + Article schema; cross-linked from all /compare pages
GitHub Action — Polsia-Inc/filtrate-scan-action
- scan-action published to GitHub Marketplace as Polsia-Inc/filtrate-scan-action@v1
- Diffs PR files, calls /v1/process for each image, posts markdown compliance table as PR comment
- Exits non-zero on GPS/EXIF threshold breach; zero config beyond API key in GitHub secrets
- Self-contained bundle with @actions/core + @actions/github + minimatch; no external runtime
Credits System + Activation Campaign + /admin/users
- credits table: API call credits purchasable via Stripe 5-pack ($X for 2,500 calls) or granted manually
- Stripe webhook branch for metadata.product === "5pack" automatically grants credits on checkout
- activation_emails table tracks drip campaign sends and conversion events per recipient
- /admin/users shows id, email, api_calls_total, has_credits, credits_remaining for targeting
Interactive API Docs — Swagger UI + Redoc + /openapi.json
- OpenAPI 3.1 spec at /openapi.json covering POST /v1/process, GET /v1/usage, POST /v1/keys
- Swagger UI at /docs/api with dark-mode styling and Try It Out enabled
- Redoc render at /docs/api/redoc for spec-first browsing
- Both endpoints added to sitemap + IndexNow; footer Developers group links all four surfaces
/trust — Trust & Security Page
- Full enterprise-facing /trust page: image lifecycle, data retention table, sub-processor list
- GDPR / CCPA / SOC2 / PCI compliance posture section; vulnerability disclosure policy
- Postmark-backed security inquiry contact form
- Added to sitemap, footer Product group, and /docs CTA
Marketplace Privacy SEO Pages
- 10 per-marketplace detail pages at /marketplaces/:slug (Poshmark, Depop, Mercari, Grailed, Vinted, etc.)
- Per-marketplace: GPS stats, redacted EXIF examples, Filtrate compliance comparison, CTAs
- 11 new sitemap entries + IndexNow ping; marketplace Audits footer section
- Programmatic SEO surface for "marketplace privacy" long-tail queries
Audit Lead Capture + 3-Email Drip
- audit_leads table captures email + marketplace + leak severity from the /audit tool
- 3-email Postmark drip: T+0 "Your results", T+2d "What this means", T+5d "Fix it with Filtrate"
- Admin endpoints: GET /admin/audit-leads, POST /admin/process-drip?step=N
- UTM-tagged utm_source=audit_drip, utm_campaign=lead_nurture on all drip links
2026 Marketplace Privacy Report
- Public research report at /reports/marketplace-privacy-2026 with headline stats and per-marketplace table
- audit_report_2026 table stores per-listing EXIF/GPS/compression results from scraped listings
- Data collection job in jobs/collectAuditData.js (~40 listings/marketplace)
- Added to sitemap + IndexNow; admin POST /admin/collect-audit-data trigger endpoint
/audit — Marketplace Privacy Audit Tool
- Interactive /audit tool: enter a marketplace listing URL, get GPS leak alert, camera fingerprint, before/after comparison
- Rate-limited: 3 audits/IP/hour; domain allowlist covers Poshmark, Depop, Grailed, Mercari, ThredUp, Vinted, eBay, Etsy
- All CTAs UTM-tagged with utm_source=audit — converts PH/HN/Dev.to traffic into signups
- Lead capture modal shown after leak is detected; feeds audit_leads drip sequence
Official SDKs — @filtrate/sdk (npm) + filtrate (PyPI)
- TypeScript SDK: Filtrate class, process({ imageUrl | imageBuffer }), full types, ESM+CJS build
- Python SDK: Filtrate(api_key) client, .process(image_url | image_file), dataclass types, py.typed marker
- GitHub Actions auto-publish on sdk-node-v* and sdk-python-v* tags
- /docs updated: SDK section leads with install commands; code tabs now show SDK first
Cold Outreach + UTM Signup Attribution
- Wave 2 cold outreach batch to Vestiaire/Grailed/Depop engineering contacts via Postmark
- cold_outreach_contacts table: contact upsert, status tracking, UTM attribution per contact
- UTM middleware captures utm_source/medium/campaign/content on every request; stored on user at signup
- GET /admin/conversions: UTM attribution dashboard showing which channels convert to signups
SEO Comparison Pages — vs Cloudinary, Sightengine, imgix
- Three dedicated /compare/:competitor pages with structured feature tables and CTAs
- Targets "filtrate vs [competitor]" search queries; cross-linked from nav and footer
- JSON-LD Article schema; added to sitemap + IndexNow
- Compare dropdown added to main nav (desktop + mobile)
Admin Invoice System + Stripe Billing Portal
- invoices table tracks monthly billing records: user_id, period, image_count, total_amount, status
- Stripe Checkout session creation for invoice payment; webhook marks invoices paid on checkout.session.completed
- Billing Portal self-serve: manage payment methods, view invoice history, cancel
- GET /admin/conversions UTM attribution dashboard; POST /admin/generate-invoices trigger
MD5 Verdict Cache — Instant Repeat-Image Results
- verdict_cache table: MD5-keyed cache of AI moderation verdicts (image_hash → verdict JSON)
- Repeat images skip the OpenAI call entirely — returns cached verdict in <50ms vs 1-5s
- Cache hit tracked on last_accessed; cold cache warms on first /v1/process call per image
- Billing unchanged — cached calls still count as billable (compliance record kept)
/docs — Developer Documentation Page
- Full /docs page: quick start, request/response reference, code examples in cURL, Node.js, Python
- GitHub Action section with copy-paste workflow snippet
- Endpoint table, error codes, rate limits, EXIF fields list
- Added to nav (desktop + mobile), footer Developers group
Stripe Checkout — Usage-Based Monthly Billing
- Stripe Checkout session created per invoice for one-click payment
- checkout.session.completed webhook marks invoice paid and emails receipt
- Monthly invoice generation script tallies usage_logs and creates invoice rows
- $0.002/image pricing hard-coded; invoice line items show image count × rate
Filtrate — Initial Launch
- POST /v1/process: strips EXIF metadata, compresses to WebP, returns AI content moderation verdict in 1-5s
- Developer signup + API key management dashboard; keys are bcrypt-hashed, only shown once
- Usage logging every billable call: api_key_id, user_id, endpoint, timestamp
- Processed WebP images stored on R2 via Polsia proxy; originals never persisted
Get release updates by email
We ship fast. Subscribe for a low-noise signal when something worth knowing lands.