Files
autoreg-skills-max/skills/apodex-batch-reg/references/apodex-otp-rate-limits.md

113 lines
4.7 KiB
Markdown

# Apodex OTP: Rate Limits & IMAP Extraction
## CRITICAL: NO-OTP Registration (discovered 2026-06-26)
Apodex creates accounts **without OTP verification**. Simply entering a new email on the sign-in page and clicking "Continue with email" creates the account server-side — the OTP dialog that appears is a frontend artefact. The account already exists.
**This changes everything:**
- No IMAP OTP extraction needed for account creation
- No rate limit (`PASSWORDLESS_SEND_RATE_LIMITED`) — it only applies to OTP endpoint, not account creation
- 12+ accounts in ~4 minutes: navigate → click Sign in → type email → click Continue → clear cookies → repeat
- NO wait between accounts
**ONLY use OTP flow when you need to LOG IN** to an existing account (e.g., to extract API key from the dashboard).
## Auth Endpoint
```
POST https://www.apodex.ai/api/auth/passwordless/send-code
Content-Type: application/json
{"email": "[REDACTED-EMAIL]"}
```
Returns:
- `200` — OTP sent (browser transitions to OTP input)
- `429` — `{"code":"PASSWORDLESS_SEND_RATE_LIMITED","message":"Operation too frequent, please try again later"}`
- `404` on `/api/auth/magic-link` — wrong endpoint, use `passwordless/send-code`
## Verify Endpoint
```
POST https://www.apodex.ai/api/auth/passwordless/verify-login
Content-Type: application/json
{"email": "[REDACTED-EMAIL]", "code": "123456"}
```
Returns:
- `200` — `{"success":true,"data":{"access_token":"<JWT>","user":{...}}}`
- The `access_token` is an Apodex JWT (`{user_id, session_id}`). Works for `www.apodex.ai/api/auth/*`, NOT for `api.apodex.ai/v1/api-keys` (returns 401 `invalid token`).
- The Supabase JWT format needed for `/v1/api-keys` is `{iss, ref, role, sub}` — but the Supabase project is DEAD.
- `400` — OTP expired or already used
## Rate Limit
- ~8-10 OTP triggers per short window before 429
- Reset: ~5-10 minutes
- Per-IP (not per-email)
- **Does NOT apply to account creation via email-only signup**
- Symptoms: email form re-renders without OTP page appearing
## IMAP OTP Extraction (Python One-Liner)
ONLY needed for key extraction from existing accounts:
```python
python -c "
import imaplib, ssl, re, email
imap = imaplib.IMAP4_SSL('secureimap.t-online.de', 993, timeout=15)
imap.login('[REDACTED-EMAIL]', 'PASSWORD')
imap.select('INBOX')
status, msgs = imap.search(None, 'FROM', 'apodex')
msg_ids = msgs[0].split()
status, data = imap.fetch(msg_ids[-1], '(RFC822)')
raw = data[0][1].decode('utf-8', errors='ignore')
msg = email.message_from_string(raw)
if msg.is_multipart():
for part in msg.walk():
if part.get_content_type() == 'text/plain':
body = part.get_payload(decode=True).decode('utf-8', errors='ignore')
codes = re.findall(r'\b\d{6}\b', body)
if codes: print(codes[0])
else:
body = msg.get_payload(decode=True).decode('utf-8', errors='ignore')
codes = re.findall(r'\b\d{6}\b', body)
if codes: print(codes[0])
imap.logout()
"
```
## Registration Flow
### PRIMARY: NO-OTP (account creation only, ~20s per account)
1. `browser_navigate('https://www.apodex.ai')` — signed-out state
2. `browser_click('Sign in')` — opens auth dialog (ref `@e9`)
3. `browser_type(email)` + `browser_click('Continue with email')` — single type, single click
4. Account created server-side immediately. OTP dialog is cosmetic — ignore it.
5. `browser_console('localStorage.clear(); sessionStorage.clear();')`
6. Repeat from step 1 — NO wait, NO rate limit
### FALLBACK: OTP (login for key extraction)
⚠️ **BLOCKED** — Supabase project is dead, so `/v1/api-keys` can't issue new keys. Only use to log into dashboard.
1. `browser_navigate('https://www.apodex.ai')`
2. `browser_click('Sign in')`
3. `browser_type(email)` + `browser_click('Continue with email')` — FIRST attempt
4. Dialog re-renders, email cleared → `browser_type(email)` + `browser_click('Continue with email')` — SECOND attempt
5. OTP page appears → `browser_snapshot()` to get refs
6. Run IMAP one-liner → get 6-digit code
7. `browser_type(otp_code)` + wait for auto-verify
8. "Free Beta" alertdialog = SUCCESS
9. Sign out: `browser_click(user_menu)` → `browser_click('Sign Out')`
10. Clear storage
## Pitfalls
- **NO-OTP is PRIMARY** — DO NOT fetch OTP for account creation
- **Rate limit 429 only applies to OTP flow** — after ~8 accounts. Ignore for NO-OTP
- **Double-type required ONLY for OTP flow** — email input gets cleared on first dialog render
- **Click, not Enter**: Enter closes the dialog instead of submitting
- **Password format**: t-online.de passwords may contain `@` (e.g., `@cottage`)
- **IMAP server**: `secureimap.t-online.de:993` (SSL), not `imap.t-online.de`
- **access_token from verify-login = Apodex JWT**, NOT Supabase JWT. Won't work for `/v1/api-keys`.