Files
last30days-skill/partner-credits-proposal.md
2026-03-05 18:43:52 -08:00

254 lines
9.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Partner Credits: Zero-Registration Free Tier for last30days Users
**Type:** Partnership proposal for ScrapeCreators
**Date:** 2026-03-05
**Status:** Draft proposal
---
## The Pitch
Every last30days user gets 100 free ScrapeCreators credits — Reddit, TikTok, Instagram — without ever visiting scrapecreators.com or creating an account. When they run out, the skill tells them where to upgrade. ScrapeCreators gets a distribution channel. last30days gets a killer default experience.
## The Problem
Right now, new last30days users hit a wall:
1. Install the skill (30 seconds)
2. Try `/last30days AI video tools`
3. Get told they need a `SCRAPECREATORS_API_KEY`
4. Have to go to scrapecreators.com, register, get a key, paste it into `.env`
5. Many never come back
The best Reddit experience requires a key. The friction kills adoption.
## The Proposal: Machine-Bound Partner Tokens
### How It Works
**ScrapeCreators side:**
1. Issue last30days a **partner ID** (e.g., `partner_last30days`)
2. Accept a new header: `X-Partner-Device: <device_hash>`
3. On first request per device hash: allocate 100 credits, no registration needed
4. Track usage: `(partner_id, device_hash) → credits_remaining`
5. When credits hit 0: return `402` with upgrade URL in response body
**last30days side:**
1. On first run, generate a **device fingerprint** and cache it locally
2. If user has no `SCRAPECREATORS_API_KEY`, send requests with partner headers instead
3. When 402 comes back, show a friendly "upgrade" message
That's it. No accounts, no OAuth, no registration flow.
### The Device Fingerprint
```python
import hashlib, platform, uuid, os
def get_device_id():
"""Generate a stable, hard-to-forge device fingerprint."""
# Use the OS-level machine ID (persists across reinstalls on most systems)
machine_id = _get_machine_id()
# Salt with the partner ID so the hash is useless outside this context
raw = f"last30days:{machine_id}"
return hashlib.sha256(raw.encode()).hexdigest()
def _get_machine_id():
"""Get the OS hardware/machine ID."""
if platform.system() == "Darwin":
# macOS: IOPlatformUUID (hardware-bound, survives OS reinstall)
import subprocess
result = subprocess.run(
["ioreg", "-rd1", "-c", "IOPlatformExpertDevice"],
capture_output=True, text=True
)
for line in result.stdout.splitlines():
if "IOPlatformUUID" in line:
return line.split('"')[-2]
elif platform.system() == "Linux":
# Linux: /etc/machine-id (set at install time)
try:
return open("/etc/machine-id").read().strip()
except FileNotFoundError:
pass
# Fallback: MAC address + hostname (less stable but reasonable)
return f"{uuid.getnode()}:{platform.node()}"
```
**Why this works:**
- macOS `IOPlatformUUID` is hardware-bound — can't change it without a new motherboard
- Linux `/etc/machine-id` is set at OS install — persists across reboots
- Hashed with `last30days:` prefix so the raw ID is never sent to ScrapeCreators
- Cached locally in `~/.config/last30days/.device_id` after first generation
### API Request Format
```
# Without partner credits (existing flow — user has their own key)
GET /v1/reddit/search?query=AI+tools
x-api-key: sc_user_abc123
# With partner credits (new — no registration needed)
GET /v1/reddit/search?query=AI+tools
x-api-key: sc_partner_last30days
X-Partner-Device: a1b2c3d4e5f6... (sha256 hex)
```
ScrapeCreators treats `sc_partner_last30days` as a special key class:
- Requires `X-Partner-Device` header
- Credits tracked per device hash, not per API key
- Rate limited per device (e.g., 10 requests/minute)
- 100 credits per unique device, lifetime
### What Counts as a Credit
One API call = one credit. A typical `/last30days` run uses roughly:
- 2-4 Reddit searches (global + subreddit drilldowns)
- 1-2 TikTok searches + 2-3 transcript fetches
- 1-2 Instagram searches + 2-3 transcript fetches
So ~10-15 credits per run. 100 credits ≈ **7-10 full research runs** before upgrade.
That's enough to get hooked.
## Abuse Prevention
### What we're defending against
| Threat | Likelihood | Impact |
|--------|-----------|--------|
| User spoofs device ID to get infinite credits | Low | Medium |
| Script generates thousands of fake device IDs | Medium | High |
| User shares partner key for non-last30days use | Low | Low |
### Defenses (simplest first)
**1. Hardware-bound device ID (primary defense)**
- macOS IOPlatformUUID can't be changed without hardware swap
- Linux machine-id requires root to change and breaks other software
- Not a cookie or config file — it's the machine itself
**2. Rate limiting per device (ScrapeCreators side)**
- 10 requests/minute per device hash
- Prevents scripted rapid-fire abuse even with valid device IDs
- Normal usage never hits this — a full run takes 60-70 seconds with natural gaps
**3. IP rate limiting on new device registrations (ScrapeCreators side)**
- Max 3 new device hashes per IP per day
- Stops "generate 1000 device IDs from one server" attacks
- Legitimate users: one machine, one device ID, done
**4. Total partner pool cap (safety valve)**
- ScrapeCreators sets a monthly cap on total partner credits (e.g., 50,000/month)
- If last30days goes viral and blows the cap, both parties renegotiate
- Prevents runaway costs from unexpected growth
### What we're NOT doing (intentional simplicity)
- No CAPTCHAs
- No email verification
- No phone verification
- No browser fingerprinting
- No token signing or crypto
- No account creation whatsoever
The goal is zero friction. The device ID is "good enough" — it stops casual abuse and scripts. A determined attacker could maybe get 200-300 free credits by VM gymnastics, but that's not worth defending against when paid plans are cheap.
## User Experience
### First run (no key configured)
```
$ /last30days AI video tools
🔍 Searching Reddit, TikTok, Instagram...
️ Using 100 free partner credits from ScrapeCreators (93 remaining)
Get your own key for unlimited use: scrapecreators.com/last30days
[... normal results ...]
```
### Credits running low
```
️ 12 partner credits remaining. Get unlimited access: scrapecreators.com/last30days
```
### Credits exhausted
```
⚠️ Free partner credits used up!
Reddit, TikTok, and Instagram require a ScrapeCreators API key.
Get one at: scrapecreators.com/last30days (100 free credits on signup, then pay-as-you-go)
Continuing with X, YouTube, Hacker News, Polymarket, and web search...
```
Key detail: the skill **doesn't stop working** — it gracefully falls back to the sources that don't need a key. The user still gets value, but they see what they're missing.
### After upgrade
```
$ echo 'SCRAPECREATORS_API_KEY=sc_abc123' >> ~/.config/last30days/.env
# Next run — partner headers no longer sent, user's own key used
```
## What ScrapeCreators Gets
1. **Distribution channel** — every last30days install is a potential paying customer
2. **Zero support burden** — no accounts to manage for free tier users
3. **Qualified leads** — users who exhaust 100 credits are proven power users
4. **Co-marketing** — "Powered by ScrapeCreators" in every skill run
5. **Usage data** — anonymous device-level usage patterns across topics
## What last30days Gets
1. **Zero-config Reddit** — install and go, no registration anywhere
2. **TikTok and Instagram included** — three sources work out of the box
3. **Lower barrier to adoption** — the #1 friction point eliminated
4. **Upgrade path built in** — natural conversion funnel
## Implementation Effort
### ScrapeCreators side (their work)
- [ ] Create partner key class with per-device credit tracking
- [ ] Accept `X-Partner-Device` header on partner keys
- [ ] Return `402` with upgrade URL when credits exhausted
- [ ] Rate limit: 10 req/min per device, 3 new devices/day per IP
- [ ] Dashboard for last30days to see aggregate partner usage
### last30days side (our work)
- [ ] `scripts/lib/device_id.py` — generate and cache device fingerprint (~30 lines)
- [ ] Update `scripts/lib/env.py` — fall back to partner auth when no user key
- [ ] Update `_sc_headers()` in reddit.py, tiktok.py, instagram.py — add partner headers
- [ ] Handle 402 response — show upgrade message, continue with other sources
- [ ] Show credits remaining in run output (from response header)
### Suggested response headers from ScrapeCreators
```
X-Partner-Credits-Remaining: 87
X-Partner-Credits-Total: 100
X-Partner-Upgrade-URL: https://scrapecreators.com/last30days
```
## Open Questions
1. **Credit pool negotiation** — what monthly cap works for ScrapeCreators?
2. **Referral tracking** — should `scrapecreators.com/last30days` give a signup bonus or revenue share?
3. **Credit count per endpoint** — should transcript fetches cost the same as searches?
4. **Expiration** — do unused partner credits expire (e.g., 90 days)?
---
## Summary
One device ID. One partner key. One header. 100 free credits. Zero registration.
The entire abuse prevention is: your computer has a hardware ID that you can't easily change. That's it. Simple, clever, and good enough.