I ran 22 directory submissions with Playwright in one day. Here is what actually blocked me. A developer who attempted to submit SongStory, a personalized song generator, to 22 SaaS and AI directories using Playwright found that only 5 submissions succeeded, with 17 failing due to site-side issues rather than automation problems. The failures included hard paywalls, platform changes, and site bugs, and the developer highlighted the importance of verifying actual rendered HTML versus marketing claims, as some directories' free tiers did not provide the expected dofollow links. Submitting a product to SaaS and AI directories is the kind of task that looks perfect for browser automation: same five fields, same "Submit" button, fifty different sites. I spent a day driving 22 of them with Playwright for SongStory https://songstory.ai/ , a personalized song generator, and only 5 submissions actually went through. The other 17 failed. Almost none of them failed for the reason I expected. Here is the real distribution, because I think the failure modes are more useful than another "how to automate forms" tutorial. | Outcome | Count | Notes | |---|---|---| | Submitted successfully | 5 | 3 fully automated, 1 needed a human for reCAPTCHA, 1 by email | | Hard paywall | 9 | No free tier at all, or free tier explicitly strips the link | | Platform changed shape | 5 | Registration closed, site became app-only, field removed | | Site-side bug or hard block | 2 | Broken form, Cloudflare | | Bad neighborhood / wrong category | 3 | Would have hurt more than helped | Note that "the automation broke" is not a row in that table. Playwright handled every form I pointed it at. What killed submissions was the state of the sites themselves. This was the most common paywall pattern, and the most interesting one. One directory, bai.tools , offers a free listing with the line "Submit without backlink for free " — a paid tier at $19 gets you the dofollow link. My first instinct was to skip it. Free tier, no link, no point. That instinct was wrong, and it is worth explaining why. I checked an existing listing on that same site with two different user agents: a normal browser and a Googlebot UA fetched via page.request.get : js const r = await page.request.get listingUrl, { headers: { 'User-Agent': 'Mozilla/5.0 compatible; Googlebot/2.1; +http://www.google.com/bot.html ' } } ; const html = await r.text ; // pull every outbound anchor and its rel attribute const links = ...html.matchAll /