# MODA (moda.app) — Clerk signup + work-email promo + API reverse AI-дизайн-агент (канвасы, сайты, бренд-киты). Free = 500 cr/мес, Pro $30 = 6000 cr/мес. Промо `CLAUDEFOUNDERS` = 90 дней Pro бесплатно без карты, авто-отмена в конце триала. ## Ключевые ограничения промо (проверено живыми 403) - Требует **work email** — gmail/outlook отбивает `403 promo_requires_work_email`. - **Один клейм на email-домен**: второй воркспейс с тем же доменом → `403 promo_domain_already_claimed`. Для масс-фарма нужен пул РАЗНЫХ неблокируемых work-доменов с catch-all. - Clerk-блоклист temp-mail: `voidash.cyou`, `*.eu.cc` (govno/musor/pomoi) → `form_email_address_blocked` при signup. `voidash.bond` проходит signup, но как домен промо-клейма одноразовый. - Redeem body key — `code`, НЕ `promo_code` (иначе 422 validation_error). ## Флоу авторега (работает, ~6 мин/акк) 1. Voidash inbox: `POST https://api.voidash.com/api/v1/inboxes {"domain": "voidash.bond"}` → address + session_key. Сообщения: `GET /messages` с `Authorization: Bearer *** key]` → поле `otp_code` напрямую (fallback regex `\b\d{6}\\b` по preview_text/body). Домены: `GET /domains`. 2. Turnstile: невидимый sitekey `0x4AAAAAAAFV93qQdS0ycilX`, action ОБЯЗАТЕЛЬНО `signup`, solve через локальный sidecar :8877 (`type: turnstile`). Smart-sitekey `0x4AAAAAAAWXJGBD7bONzLBd`. 3. Clerk signup в page-контексте: `window.Clerk.client.signUp.create({emailAddress, password, captchaToken, unsafeMetadata:{referral_code}})` → status `missing_requirements` это НОРМА (ждёт email verify). PK: `pk_live_Y2xlcmsubW9kYS5hcHAk`. 4. Verify: `signUp.prepareEmailAddressVerification({strategy:'email_code'})` (или `prepareVerification({strategy:'email_code'})`) → код из voidash → `signUp.attemptVerification({code, strategy:'email_code'})` — **strategy ОБЯЗАТЕЛЕН в том же вызове**, без него `form_param_missing`. Status `complete` + `createdSessionId` → `Clerk.setActive({session: id})`. 5. MODA provision: `POST https://api.moda.app/api/v1/users/me/sync` с Bearer JWT → создаёт user+org, возвращает `organizations[].id`. 6. Redeem: `POST /api/v1/organizations/{org}/billing/redeem-promo {"code": "CLAUDEFOUNDERS"}` → 200 `{credits_granted, pro_trial_days: 90, monthly_credits: 6000}`. ## Альтернативный путь на существующем gmail-акке (work email вторым) Password-reset обходит session-reverification тупик: `POST clerk.moda.app/v1/client/sign_ins` strategy `reset_password_email_code` → код из IMAP → `client.signIn.attemptFirstFactor({code, password, strategy})` **одним вызовом** (раздельные падают) → setActive → fresh-сессия. Затем `user.createEmailAddress({email})` — payload `{email}`, НЕ `{email_address}` (минифицированный исходник: `let{email:t}=e`) → prepare/attempt verification → `user.update({primaryEmailAddressId: idn})` + `user.reload()` → sync → redeem. Rate limit на reset-коды ~4 мин между попытками. ## Clerk JS API — проверенные сигнатуры - Логин: `client.signIn.create({identifier, password})` → `setActive({session: createdSessionId})`. Функции `window.Clerk.signIn()` НЕ существует. - JWT живёт ~60с — всегда `session.getToken({skipCache:true})` непосредственно перед API-вызовом. - `session.prepareFirstFactorVerification({strategy:'email_code'})` для reverification — ни один вариант action не даёт стабильного OK; не тратить время, использовать reset-password путь. - Сохранённые cookies браузера теряют Clerk-сессию (`GET /v1/client` → `sessions: []`) — перелогин по паролю надёжнее реюза cookie-файлов. ## API-карта (реверс из app-чанков + живые 200) - Billing: `/api/v1/organizations/{org}/billing/{status,usage,credit-details,credit-bundles,redeem-promo,checkout}`. Бандлы: $10=2000cr, $25=5000cr, $50=10000cr, $100=22000cr. Paid: до 10 seats, `credits_per_seat: 6000` — инвайты шарят квоту. - Referrals: `/organizations/{org}/referrals/{code,stats}` (свой код на воркспейс), `/api/v1/referrals/claim`. - Генерация: `/api/v1/conversations/omni/{id}` + `/turns/{id}` (агент), `/api/v1/canvases`, `/api/v1/websites` (+`/duplicate`), `/remove-background`, `/brand-kits`, `/memory/*`. Liveblocks-коллаб, Figma OAuth. - **Генерации идут НЕ через REST, а через WebSocket** (полный протокол из бандла): `wss://api.moda.app/ws/unified/{team_id}?token=&session_id=`. Отправка задачи `{"type":"agent.execute_task","canvasId":...,"task":"<промпт>","requestId":...}`; отмена `agent.cancel_job`/`agent.cancel_task`; ресинк `agent.catch_up {canvasId, fromSequence}`; привязка треда `agent.set_thread {thread_id, conversation_id}`; keepalive `ping`/`pong`, ре-авторизация `reauth`/`reauth_ack`. Стрим ответа — enum 60+ типов: `agent.thinking_chunk` → `agent.assistant_text_chunk` → `agent.tool_call`/`tool_response` → `agent.canvas_update` → `agent.token_usage` → `agent.session_completed`. REST omni-эндпоинты — только чтение (detail, scene-baselines, checkpoint-activity, PATCH working-state). Полный REST-каталог = 130 уникальных путей (regex-экстракт `[`"](/api/v\d/...)[`"]` по app-чанкам). - Модели (AGENT_MODEL_CATALOG): primary — opus-5, sonnet-5.5, gpt-6.1-sol (free-tier ok); more — opus-4.8, sonnet-5, fable-5.1/fable-5 (requiresPaid), haiku-4.5, gpt-5.6-sol/terra/luna, kimi-k2.5/k2.6/k3 (1M ctx, Fireworks). UI-тиры lite/standard/pro/pro-fast; усилия none..max; fast-транспорт anthropic-fast/openai-priority. Image: nano-banana-lite. ## Питфолы автоматизации - **Fresh browser на каждый аккаунт**: общий browser с несколькими context'ами переносит Clerk-сессию → второй акк получает org ПЕРВОГО (sync_email совпадает, ref-код тот же). Признак: одинаковый org/ref у разных email в логе. - Cloudflare: ждать пока title не содержит «moment»; инъекция только `cf_clearance`, `__cf_bm`, `_cfuvid`. - Тулкит лежит в `tmp/moda-farm/` (farm_reg.py, redeem_existing.py, api_probe.py); публичная копия — github ArthurMonteiro08586/moda-farm.