Files
autoreg-skills-max/skills/ai-provider-autoreg/references/attio-merlin-company-email-recon.md

5.5 KiB

Attio (app.attio.com) — company-email signup recon (2026-09-27)

Target: farm Attio accounts to feed attio-merlin-proxy (TopDeckhandBlock) — an OpenAI-compat gateway over Attio Merlin (Ask Attio, in-app AI with Claude Opus 5.5 / Sonnet 4.6 / GPT-6 Sol / Gemini 3.8). Proxy needs a logged-in browser cookie + workspace slug per account.

STATUS: signup flow reversed, OTP delivery confirmed via tempmail.lol; redemption step NOT yet completed (wrong OTP format extracted). Recon below is live-verified unless marked.

Auth protocol (pure HTTP, no browser, no captcha)

POST https://app.attio.com/api/auth/email-sign-in
  headers: content-type: application/json
           x-attio-locale: en
           x-attio-platform: web-app
           x-attio-platform-version: <hash from current main.bundle.js>
           x-attio-execution-id: <uuid4>   # optional
  body: {"email_address": "<email>", "origin": "/signup"}
  → 201 {"authentication_strategy":"temporary-password"}   (code mailed)
  → 200 + SAML redirect_url if domain is SAML-managed
  → 400 {"message":"Please retry with a company email"}    (domain blocklisted)
  → 404 = no account associated (existing-user path differs)

POST https://app.attio.com/api/auth/temporary-code
  body: {"email_address":"<email>","temporary_code_candidate":"<code>"}
  → 200 success (session cookie set) / 401 bad code / 404 email-not-found

GET /api/auth/whoami, GET /api/common/workspaces  (cookie auth)

Other endpoints found in main.bundle.js: /api/auth/temporary-password, /auth/join/$workspaceSlug, onboarding stages WELCOME→ABOUT_YOU→VERIFY_EMAIL→CONCIERGE. The x-attio-platform-version value lives in the current main.bundle.<hash>.js (grab fresh from signup page HTML).

Company-email gate — LIVE domain matrix (2026-09-27)

Attio blocklists free consumer providers. The check runs on the literal domain string, and it validates AGAINST a blocklist (everything not listed passes):

Verdict Domains
BLOCKED (400) gmail.com (incl. +aliases), outlook.com, hotmail.com, proton.me, icloud.com, mail.ru, inbox.ru, list.ru, bk.ru, aol.com, fastmail.com, t-online.de, yandex.ru, guerrillamailblock.com, mailinator.com, sharklasers.com
PASSES (201) zoho.com, tutanota.com, yandex.com, rambler.ru, gmx.com, reforrm.me, darkgate.loc.cc, [REDACTED-NAME].loc.cc (own domains), grr.la, guerrillamail.com, spam4.me, tempmail.lol, inboxbear.com, indigo.com, punkproof.com, 1secmail.com, dropmail.me, kr.auroracovia.com, hn.auroracovia.com, us.imagesthere.com, u2h.inovel26.com

Key quirks:

  • Literal mail.tm passes the probe, but mail.tm's real issued domain (uberip.com) is BLOCKED — always probe the domain the provider actually serves, not its brand name.
  • GuerrillaMail API forces issued addresses to @guerrillamailblock.com (blocked) even though @guerrillamail.com literal passes — unusable for Attio.
  • tempmail.lol issues rotating domains (auroracovia.com variants, imagesthere.com, inovel26.com) — all observed variants PASS.

OTP mail (LIVE: delivered twice via tempmail.lol)

Subject: "🔑 Your Attio Temporary Password" — arrives within ~10-30s. WARNING: naive \b(\d{6})\b regex over the whole HTML picks up CSS junk numbers (353535/767676 repeated dozens of times) and redemption fails with 401 "could not be verified". The real credential is a TEMPORARY PASSWORD (strategy name!) — parse the styled/large-font element or text near "temporary password", not the first 6-digit match. Strip tags first, then locate the code in clean text. (Not yet resolved — next step.)

Tempmail.lol read API (confirmed this session)

GET https://api.tempmail.lol/generate        → {address, token}
GET https://api.tempmail.lol/v2/inbox?token=*** → {"email": [ {...mail...} ]}

Response key is email (list). Free-tier yield is partial (~50%): a sign-in can 201 yet the mailbox stays empty — loop with fresh generate() per attempt (5 attempts pattern worked: got mail on attempts 1-2, empty on 3).

Own-domain path (cleanest, if tempmail flakes)

  1. nodeloc.com free domain (see free-domain-registration skill; darkgate.loc.cc id=4971 already owned, [REDACTED-NAME]+darkgate@gmail.com / Reform123!@#).
  2. MX → mx1/mx2.improvmx.com + TXT spf via nodeloc DNS API (DONE 2026-09-27: records 10463-10465, synced_to_powerdns:true).
  3. ImprovMX catch-all forward → gmail: NOT automated — ImprovMX account management API is opaque (api.improvmx.com/v3/auth/login wants a domain field and rejects; SPA bundle builds paths dynamically). Needs one manual browser setup of the forward. After that, ANY *@darkgate.loc.cc works: Attio sign-in → mail lands in [REDACTED-NAME]@gmail.com → IMAP read. Unlimited accounts per domain, zero tempmail flakiness.

Zoho as company-email fallback — BLOCKED

Zoho signup (accounts.zoho.com/register) requires MOBILE_NUMBER SMS verification + CSRF digest (signupDigest). No free mass path without an SMS service (365sms/sms-activate). imap.zoho.com:993 is reachable and zoho.com passes Attio's filter, so IF SMS is available, zoho mailboxes are a durable Attio account source.

Scripts (this session, tmp/attio_autoreg/)

  • probe_signin.py <email> — Attio filter probe for any domain
  • probe_temp2.py — batch domain matrix
  • attio_v4.py — multi-attempt reg with full mail JSON dump (extend: fix password extraction → temporary-code redeem → whoami → create workspace → slug+cookie)
  • After account works: cookie string (attio-app-session=...; attio-session=<JWT>) + slug go into attio-accounts.json for the proxy.