• Welcome to DNForum.com - Domain Investor Forum, Free Domain Marketplace and a community for 45+ domain pros
    If you are new to domains and looking to buy, sell and learn about domains then you have come to the right place. DNForum is the oldest global domain name community on the internet and continues to grow every day. There are over 45,000 domainers on DNForum doing everything from buying domains, selling domains, using our free in-house built tools, learning about domains and discussing domains. Take a minute and Register.

DNForum SLD Checker vs dotDB: a transparent test, real gains and issues to fix

HelmutsHelmuts is verified member.

Domain Summit | HostMaria
DNF Staff
Registrar
Hosting Provider
DNForum.club
Joined
Mar 29, 2014
Messages
2,652
Reaction score
1,022
I was excited by the comparisons in Biraj's SLD Checker update thread.

This morning, I also wanted to check whether our tool really provides better results for its core task: finding the same domain keyword across different extensions.

And, a selfish one > wanted to brag about it a little on our newsletter :)

So, I asked my Hermes AI assistant to run a fresh independent comparison work, preserve the results and investigate discrepancies. The instruction was to test both tools fairly, not to make DNForum win.
Hermes_FDx7VeEPUD.webp


For transparency: I own DNForum, and this test was commissioned by me. It is an AI-assisted comparison with supporting evidence, not an independent third-party certification.

The findings include genuine DNForum wins, results where dotDB leads, and issues in our own results that deserve attention. I am publishing all of them.

What was completed

The test used a fixed sample of 20 keywords. All 20 were checked on DNForum, but only 10 valid paired comparisons were completed before dotDB's daily search limit prevented further results.
Hermes_8UUMZB8I88.webp


Attempts to resume did not remove the limit in the test browser session. The remaining comparisons are therefore incomplete.

The limited dotDB pages displayed dummy rows and zero counts. These were excluded, not treated as genuine zero-result searches. This access limitation is not evidence that DNForum has better data.

How the comparison worked

The comparison focused on the exact keyword row across all extensions and all domain statuses.

For example, the search for "cloud" compared cloud.com, cloud.net, cloud.co.uk and other exact-name results. It did not compare the total number of domains containing "cloud" somewhere in a longer name.

A few important details:
  • The sample was deliberately varied, not random or statistically representative.
  • "helmuts", "liene" and "api" reproduced earlier examples from the update thread. The other 17 keywords broadened the test.
  • Extension counts include registration suffixes such as .co.uk, not only top-level domains.
  • DNForum results were collected from its public server-rendered /sld?keyword= pages. The "cloud" result was also checked in the rendered browser interface.
  • dotDB results were collected from its live Chrome-rendered search pages.
  • The extracted extension lists were deduplicated and checked against the displayed counts.
  • This was not a speed test or a fully equivalent test of both interactive search workflows.

The 10 completed comparisons

DNForum's counts changed between the initial searches and later repeat searches. Both observations are included below.

KeywordDNForum initialDNForum repeatdotDB
helmuts12128
liene192121
api843844791
cloud706814806
hosting259530535
domain307570566
bitcoin500825830
wallet538557553
solar447515507
coffee439477481

On the repeat observations:
  • DNForum returned more extensions for 6 keywords.
  • dotDB returned more for 3 keywords.
  • 1 keyword was tied.
  • The combined counts were 5,165 for DNForum and 5,098 for dotDB.
  • DNForum's net count advantage was 67, approximately 1.31%.

These are reported coverage counts, not independently validated registration totals.

The changing counts are important

On the initial observations, DNForum led on only 2 of the 10 paired searches. On the repeat observations, it led on 6.

Some changes were substantial:
  • hosting: 259 to 530
  • domain: 307 to 570
  • bitcoin: 500 to 825
  • cloud: 706 to 814

This behaviour is consistent with the live fallback and enrichment described in the development thread, but this test did not establish the precise cause.

The repeat figures are a second snapshot. They are not proof that every background check had finished.

For a stronger comparison, we need to distinguish initial stored results from later enriched results and make it clear when a search is still being updated.

Genuine DNForum wins: registered domains that dotDB missed

DNForum returned helmuts.co.uk and helmuts.online. Neither appeared in dotDB's exact "helmuts" row.

Registry checks supported both results:
  • Nominet RDAP returned a domain record for helmuts.co.uk.
  • Radix RDAP returned a domain record for helmuts.online.

Both names returned NXDOMAIN in the DNS A-record checks performed during the test.

That is a useful reminder: a domain can be registered without resolving in DNS. An unsuccessful DNS lookup does not mean a domain is available to register.

My earlier "helmuts" example therefore has substance beyond a higher displayed number.

An accuracy issue in our results: liene.fr

DNForum returned liene.fr, but AFNIC's authoritative RDAP returned HTTP 404 with this message:

No domain corresponding to liene.fr has been found

That is evidence of a stale or false-positive result at the time of testing. It deserves investigation.

I do not want us celebrating additional results while ignoring whether those results are correct.

A wildcard-DNS warning: helmuts.org.de

DNForum also included helmuts.org.de.

It resolved to 64.190.63.222. However, a freshly generated random control name, dnf-audit-b0611553912b40968b.org.de, resolved to exactly the same address.

This indicates wildcard DNS under .org.de.

It means that DNS resolution alone cannot establish that helmuts.org.de is a separately registered name. It does not, by itself, prove that the particular name has no separately provisioned record.

This is another area where our discovery and validation logic needs careful checking.

Similar totals can hide very different results

Across the ten completed comparisons, the extension lists contained:
  • 492 names found only in DNForum.
  • 425 names found only in dotDB.

For "cloud", the overall count differed by just eight, yet there were 85 DNForum-only results and 77 dotDB-only results.

For "liene", both tools returned 21 extensions on the repeat comparison, but each had three extensions missing from the other.

A matching total does not mean matching coverage. A slightly higher total does not mean one tool contains everything the other tool found.

The remaining ten keywords

These DNForum observations are included for completeness. They are not completed head-to-head comparisons.

KeywordDNForum countdotDB test status
garden350Daily limit
insurance499Daily limit
riga144Daily limit
kempten42Daily limit
nairobi102Daily limit
bluebird197Not submitted after persistent limit
northstar263Not submitted after persistent limit
cleverfox31Not submitted after persistent limit
pixelnest49Not submitted after persistent limit
green-harbor3Not submitted after persistent limit

What this test does not establish

This is a small, partial comparison. It does not establish:
  • That DNForum is more accurate overall.
  • That either tool has complete registration coverage.
  • That DNForum's related-keyword results are better.
  • That one tool is faster.
  • That Active, Parked and Inactive classifications are correct.
  • How the tools compare across their paid features.
  • How much either tool has improved historically.

The DNS discrepancy checks were diagnostic spot checks, not a representative accuracy measurement. DNS success alone does not prove registration, NXDOMAIN does not prove availability, and SERVFAIL is inconclusive.

My conclusion

I am pleased to see DNForum competing this closely and finding additional registered domains. Biraj deserves credit for the work behind that.

However, I would not use this test to claim that we have generally beaten dotDB.

The conclusion I am comfortable publishing is:

DNForum SLD Checker is competitive with dotDB on exact-match extension discovery and found additional registered domains in these spot checks. Coverage varies by keyword, and neither tool should be treated as a complete registration record.

The next useful work is to investigate liene.fr, check wildcard handling and registration-suffix boundaries, make the enrichment process clearer to users, and complete the remaining paired searches with sufficient dotDB access.

I would rather publish a result that helps us improve than a flattering comparison that members cannot trust.

Attached files

I am including all three files so members can inspect the findings:
  • comparison.csv: the 20-keyword comparison, including missing dotDB results.
  • report.md: the fuller methodology, findings and limitations.
  • benchmark-evidence.zip: saved result data, extension differences, DNS checks, RDAP responses and supporting files.

The files preserve the observations from the test. Live search, DNS and RDAP results can change after publication.

Reference sources

Original development update:
https://www.dnforum.com/threads/update-on-sld-checker.630679/page-4#post-2434341

DNForum SLD Checker:
https://www.dnforum.com/sld

DNForum exact "helmuts" search:
https://www.dnforum.com/sld?keyword=helmuts

dotDB exact "helmuts" row within its search results:
https://dotdb.com/search?keyword=helmuts&position=any

Nominet RDAP, helmuts.co.uk:
https://rdap.nominet.uk/uk/domain/helmuts.co.uk

Radix RDAP, helmuts.online:
https://rdap.radix.host/rdap/domain/helmuts.online

AFNIC RDAP, liene.fr:
https://rdap.nic.fr/domain/liene.fr

Google DNS, helmuts.org.de:
https://dns.google/resolve?name=helmuts.org.de&type=A

Google DNS, random .org.de control:
https://dns.google/resolve?name=dnf-audit-b0611553912b40968b.org.de&type=A

Happy Tuesday!!
Helmuts

Your thoughts? :)

winning game of thrones GIF by MOOT
 
If you spot a mistake in the method, have an explanation for one of the discrepancies, or can reproduce a different result, please share the keyword, filters and time of your check. Corrections are welcome.

If you want to run a similar test, my prompt was:
Code:
I want to check if dnforum.com/threads/update-on-sld-checker.630679/page-4 is true and DNForum's SLD checker dnforum.com/sld provides better results for the core task than dotdb.com . Run an independent test with 20 domains and test both

Would love to see the test results of your agents.

.. a little bragging - have you noticed that you don't hit limits with us? ;)
 
and, yes :) .. we’re aware of a small issue with our SLD Checker: entering a full domain such as idealimage.com can limit the results to that extension. For now, please search using just the name, for example idealimage, to see results across extensions.

meanwhile, @birajst is on it .. applying a fix as I write this

Thank you for patience :)

brave_5oK10RiiTx.webp


brave_RPNRhxMVx8.webp
 
@Helmuts this is resolved now 👍 Full domain searches should work across extensions properly.

Perfect!! Thank you :)

.. meanwhile, can't wait when we are able to announce the killer new feature you are working on!! :) .. don't worry currently about the few current issues and points where dotdb are still winning - overall, I think, we already beat their ass :) .. as awesome as they are :)

awesome netflix GIF by Our Planet
 
Hello everyone!

Big update for SLD Checker!

You can now use SLD Checker directly inside ChatGPT and Claude. Just ask naturally and it will check domains for you.

For example you can say:

"Check atlas across all TLDs"
"Show me all active extensions for vertex"

And it will return Active, Parked and Inactive results right inside your conversation.

To get started, click the Use SLD Checker with AI button at the top right of the SLD Checker page. You will find a simple setup guide for both ChatGPT and Claude there.

More AI platforms coming soon! 😊

1789658855611.webp
 
Hi

is the gpt integrated with sld checker or requires separate download?

tia

imo...

Hi @Biggie - the task that @birajst was working lately > allowing agents and LLMs using our SLD Checker tool without substantial restrictions.. making it "machine friendly".. in return, we are hoping to get "reference traffic" from LLMs - something like "this data is provided by DNForum's SLD checker"

.. let us see how if the 1st puppy swims :) .. now, testing time.. if you use OpenClaw, Hermes, GrokBot or any other agents - could you help us testing DNForum's SLD checker? .. does it easily access the SLD Checker and is it easy for it to read the data?

Test Drive Toa GIF by The Ops Authority | Natalie Gingrich
 
@birajst, I have just run a test with "Solar Pro4" and it got stuck. Asked it to write a report.

:) #workinprogress

===

❯ write a detailed report I can copy/paste to the developer of this tool of your test results: the workflow you took and findings, and where you got stuck. provide
full information for the developer

┊ [showing live tail; omitted 1 lines / 51 chars]
atlas 675 477 .ac, .ac.cn, .ac.uk, ...

The table body `<tbody id="domain-table-body">` contains `<tr>` rows with four cells: keyword, TLD count, active count, and a comma-separated list of extension
links (each is an `<a href="https://keyword.tld">` tagged with a status CSS class: `text-success` = active, `text-warning` = parked, `text-danger` = inactive).
### What this means
This is the easiest external access path. No JavaScript required, no CAPTCHA triggered (at least for this single lookup), and the result is fully in the initial
HTML. An external caller can `GET /sld?keyword=WORD` and parse the table.
**Filtering** also works through the same mechanism — the JS app reads `filters` state and builds the API URL with `&matchType=...&status=...&extensions=...`.
The server-side `/sld?keyword=...` endpoint likely accepts the same params; I did not exhaustively test every filter combination but the form's GET action and
the JS `buildSingleSearchUrl()` both point at the same API shape, so URL params should carry through.
**Bulk mode** — the JS `POST /api/v1/tools/bulk-search` with `{"keywords":["a","b"],"page":1,"limit":50}` is the bulk path; the server-rendered GET is
single-keyword only.
### Known gap
The server-rendered page is a starting snapshot. The JS app adds pagination (infinite scroll, `loadDomains()` fetching `/api/v2/tools/search?page=2...`) and an
"exact TLD live fallback" polling loop that enriches results after the initial load. If you only use the GET, you get the initial page — likely the first 20
results (the JS default `limit=20` in `buildSingleSearchUrl`). To get all rows you'd need the API + pagination, which falls into Path B.
---
## 3. Path B — JS App + API + reCAPTCHA
### API endpoints discovered from JS (`/js/hmbiraj/sld/index.js`)
**Single search (GET):**

GET https://sld.dnforum.com/api/v2/tool...[&status=STATUS][&extensions=COMMA-SEPARATED]

- `matchType` values: `contains`, `starts_with`, `ends_with`, `exact` (from the filter UI — "Contains / Starts with / Ends with / Exact only")
- `status` values: `active`, `parked`, `inactive` (blank = any)
- `extensions`: comma-separated, e.g. `.com,.net,.org.uk`
- Response shape (from JS `extractDomainRows`/`extractPagination`): `{ status: "success", data: [...domain rows...], data.pagination: { hasMore: bool } }` — or
wrapped as `{ data: { data: [...], pagination: {...} } }`.
- A row looks like: `{ keyword, tldsCount, tldsActiveCount, extensions: [{extension, status}, ...], isLiveFallback, liveDomain, liveEvidence, checkedAt }`.
**Bulk search (POST):**

POST https://sld.dnforum.com/api/v1/tools/bulk-search
Content-Type: application/json
Body: { "keywords": ["kw1","kw2",...], "page": 1, "limit": 50 }

- Max 50 keywords (configurable via `data-bulk-limit` on `#sld-app`, default 50).
- Response same shape as single search.
**CAPTCHA verify (POST):**

POST https://sld.dnforum.com/api/v1/client/verify-captcha
Content-Type: application/json
Body: { "token": "RECAPTCHA_TOKEN" }

- Returns `{ success: true }` on valid token; sets a session flag in sessionStorage (`session_established = "1"`).
- After a successful verify, subsequent API calls within the session are allowed.
**Exact-TLD live fallback (GET, polled):**

GET https://sld.dnforum.com/api/v2/tools/exact-tld-fallback?keyword=ENCODED

- Pollable endpoint; the JS polls it after an initial search if `responseData.liveFallback === true`.
- Response: `{ status: "success", data: { ux: { status, found, completed, queued, enabled }, exactResult: { keyword, tldsCount, tldsActiveCount, extensions:
[...] }, results: [...] } }`.
- Status values: `idle`, `running`, `completed`, `disabled`, `failed`, `error`, `unavailable`, `saturated`.
### reCAPTCHA details
- Site key: `6Le-JbUsAAAAAIZZJZoqmg9kNdAY0tBru5NmeQoT`
- Widget: invisible, rendered into `#recaptcha-container` via `grecaptcha.render(...)` with `size: "invisible"`, `callback: handleGoogleToken`.
- Initialization: Google's `recaptcha__en.js` loads, calls `window.onRecaptchaLoad`, which calls `window.initSldRecaptcha()` if `window.__sldRecaptchaLoaded` is
set.
- Trigger: on API 401/403/429, the JS calls `grecaptcha.execute(recaptchaWidgetId)`, Google returns a token, `handleGoogleToken(token)` POSTs it to
`/api/v1/client/verify-captcha`, and on success sets the session and re-runs `loadDomains()`.
### What I observed in practice
1. Navigated to `/sld/`, page loads, reCAPTCHA badge present.
2. Typing into `#search-input` and clicking `#search-btn` correctly submits the form (JS `searchForm.addEventListener("submit", ...)`).
3. The table initially shows the header row only; the JS `loadDomains()` fires and the table populates via the API. On my first attempts the table stayed at
header-only — the search appeared to either be blocked by CAPTCHA (the JS would show "Verifying..." and then re-trigger) or the fetch was failing silently.
4. Using the direct URL `GET /sld?keyword=atlas` bypassed all of this and returned a fully populated table immediately — which strongly suggests the server
renders an initial result when keyword is in the query string, without needing the JS API path.
### Where I got stuck
I did not complete a full CAPTCHA → verify → API → paginate flow from scratch in the browser. The friction points:
- **No programmatic way to solve reCAPTCHA.** I can trigger `grecaptcha.execute()` from JS, get the token, and POST it — but the token is only valid if the
reCAPTCHA challenge actually passes on Google's side. In a headless/automated browser context, the invisible widget may fail or require a real user gesture. I
can't complete the challenge.
- **Session lifecycle unknown.** After verify, how long does the session last? The JS stores `session_established` in sessionStorage — that's browser-session
scoped, cleared on tab close. An external caller would need to re-verify every session (every new browser instance / every fresh tab). There's no API token
issued — just an opaque session.
- **Rate limits.** 429 responses trigger the CAPTCHA flow. The limits are not documented; repeated automated calls would burn through CAPTCHA retries (JS caps
retries at `MAX_CAPTCHA_RETRIES = 1`, then shows "verificationFailedRefresh").
### What would need to work for Path B to be "comfortable"
1. A registered API key or token that bypasses reCAPTCHA — none documented.
2. Or, accept that every new browser session requires a human to solve the invisible reCAPTCHA once, then automation can proceed until the session dies.
3. Or, the server-rendered `GET /sld?keyword=` path is the intended external interface and the JS app is just the interactive wrapper — in which case the limits
and pagination of that GET endpoint need to be documented.
---
## 4. Path C — MCP Endpoint `https://sld.dnforum.com/mcp`
### What I tried
- **Python urllib POST** with a proper MCP `initialize` JSON-RPC message → 403 / `{"error":"invalid_request"}` (after adding browser headers; first attempt was
403 Cloudflare `error code: 1010`).
- **Python urllib GET** → 405 Method Not Allowed.
- **Python urllib POST empty body** → 400 Bad Request.
- **Python urllib POST with JSON-RPC initialize as single line** → 400 Bad Request.
- **Browser `fetch()` from page JS** to `https://sld.dnforum.com/mcp` → `TypeError: Failed to fetch` (CORS — the browser blocks the cross-origin request).
### Analysis
MCP (Model Context Protocol) uses either:
- **streamable HTTP** — an initial POST establishes a session, then JSON-RPC messages flow bidirectionally over the same connection, or
- **SSE** — server-sent events for notifications.
Both require a persistent bidirectional transport. A simple `urllib.request.urlopen` or one-shot `fetch` cannot do this. The MCP client (Claude desktop, ChatGPT
plugin host) is designed to hold that connection open.
The 403/405/400 responses suggest the server is reachable but rejects improperly-formed MCP transport. The browser CORS failure (`Failed to fetch`) is the real
blocker for any in-browser use — the MCP endpoint does not send `Access-Control-Allow-Origin` for cross-origin browser `fetch`.
The documented "Use SLD Checker with AI" page (https://www.dnforum.com/sld/ai) describes:
- ChatGPT: install a Skill (`sld-checker-skill.zip`), which presumably runs the MCP connection server-side within ChatGPT's plugin runtime.
- Claude: add a custom connector with MCP URL `https://sld.dnforum.com/mcp`, no auth. Claude's connector runtime runs server-side and can hold the MCP stream.
**Conclusion:** The MCP endpoint is reachable and functional only from an MCP client runtime (Claude, ChatGPT plugin host) that runs server-side / same-origin.
It is **not** accessible from a browser JS context (CORS) or from a simple HTTP caller (transport mismatch). An external automation outside those platforms
cannot use it directly.
---
## 5. Technical Inventory for the Developer
### Page assets
| Resource | URL | Notes |
|---|---|---|
| SLD Checker page | `https://www.dnforum.com/sld/` | XenForo-based site, cookie wall, reCAPTCHA badge |
| App JS | `https://www.dnforum.com/js/hmbiraj/sld/index.js?v=f1c90bee` | Main app logic — full source readable |
| reCAPTCHA | `https://www.google.com/recaptcha/api.js?onload=onRecaptchaLoad&render=explicit` | Invisible widget |
| reCAPTCHA JS | `https://www.gstatic.com/recaptcha/releases/BnqMGSY_YP4cCmbNINHpJPkd/recaptcha__en.js` | Google's runtime |
### `#sld-app` dataset attributes (from JS `config` reading)
| Attribute | Default | Meaning |
|---|---|---|
| `data-api-url` | `https://sld.dnforum.com` | Base URL for all API calls |
| `data-recaptcha-site-key` | `6Le-JbUsAAAAAIZZJZoqmg9kNdAY0tBru5NmeQoT` | reCAPTCHA site key |
| `data-exact-tld-live-fallback-enabled` | `true` | Whether live fallback polling is on |
| `data-exact-tld-fallback-path` | `/api/v2/tools/exact-tld-fallback` | Fallback poll endpoint |
| `data-exact-tld-fallback-poll-interval` | `1000` (ms) | Poll interval |
| `data-bulk-limit` | `50` | Max bulk keywords |
### DOM elements of interest
| Element ID / selector | Role |
|---|---|
| `#sld-app` | Root; holds `data-*` config |
| `#search-input` | Single-keyword input (`name="keyword"`) |
| `#search-btn` | Submit button |
| `#bulk-mode-toggle` | Checkbox to switch to bulk mode |
| `#bulk-input` | Bulk keyword input (comma/Enter separated) |
| `#search-form` | `<form action="/sld/" method="get">` — submit triggers JS handler |
| `#domain-table-body` | `<tbody>` where results render |
| `#recaptcha-container` | Invisible reCAPTCHA widget target |
| `#advanced-filters-panel` | Filters UI (matchType, status, extensions) |
| `#extensions-modal` | Modal showing full extension list for a row |
### API summary
| Method | Endpoint | Auth/CAPTCHA | Purpose |
|---|---|---|---|
| GET | `/sld?keyword=X` | None observed | Server-rendered initial result (single keyword) |
| GET | `/api/v2/tools/search?keyword=X&page=N&limit=20&matchType=...&status=...&extensions=...` | CAPTCHA on first call per session | JS app single-keyword
search, paginated |
| POST | `/api/v1/tools/bulk-search` | CAPTCHA on first call per session | Bulk search, JSON body |
| POST | `/api/v1/client/verify-captcha` | — | Submit reCAPTCHA token; sets session |
| GET | `/api/v2/tools/exact-tld-fallback?keyword=X` | — (within session) | Live-fallback polling for exact-match enrichment |
### Response shapes (from JS parsing logic)
- **search/bulk-search success:** `{ status: "success", data: [ domainRow, ... ], data.pagination: { hasMore: bool } }` or nested `{ data: { data: [...],
pagination: {...} } }`.
- **domainRow:** `{ keyword, tldsCount, tldsActiveCount, extensions: [{extension, status}, ...], isLiveFallback, liveDomain, liveEvidence, checkedAt }`.
- **extension.status:** one of `active`, `parked`, `inactive`, `unknown`.
- **verify-captcha success:** `{ success: true }`.
- **exact-tld-fallback success:** `{ status: "success", data: { ux: { status, found, completed, queued, enabled }, exactResult: { keyword, tldsCount,
tldsActiveCount, extensions: [...] }, results: [...] } }`.
### reCAPTCHA flow (JS-derived)
1. Page loads, Google recaptcha script loads, `window.onRecaptchaLoad` fires.
2. `window.__sldRecaptchaLoaded` is truthy → `window.initSldRecaptcha()` runs → `grecaptcha.render("recaptcha-container", { sitekey, size:"invisible", callback:
handleGoogleToken, "error-callback":..., "expired-callback":... })`.
3. On API 401/403/429: `grecaptcha.execute(widgetId)` → Google returns token → `handleGoogleToken(token)` POSTs to `/api/v1/client/verify-captcha` → on
`{success:true}` sets `sessionStorage.setItem("session_established","1")` and re-runs `loadDomains()`.
4. Retries capped at 1; after that shows "verificationFailedRefresh".
5. `grecaptcha.reset(widgetId)` after successful verify.
## 6. Where Things Stuck / Open Questions
─────────────────────── ───────────────────────────────────────────────────────────────
#sld-app Root; holds data-* config
#search-input Single-keyword input (name="keyword")
#search-btn Submit button
#bulk-mode-toggle Checkbox to switch to bulk mode
#bulk-input Bulk keyword input (comma/Enter separated)
#search-form <form action="/sld/" method="get"> — submit triggers JS handler
#domain-table-body <tbody> where results render
#recaptcha-container Invisible reCAPTCHA widget target
#advanced-filters-panel Filters UI (matchType, status, extensions)
#extensions-modal Modal showing full extension list for a row

API summary

Method Endpoint Auth/CAPTCHA Purpose
────── ────────────────────────────────────────────────────────────────────────────────────── ──────────────────────── ──────────────────────────────────
GET /sld?keyword=X None observed Server-rendered initial result
(single keyword)
GET /api/v2/tools/search?keyword=X&page=N&limit=20&matchType=...&status=...&extensions=... CAPTCHA on first call JS app single-keyword search,
per session paginated
POST /api/v1/tools/bulk-search CAPTCHA on first call Bulk search, JSON body
per session
POST /api/v1/client/verify-captcha — Submit reCAPTCHA token; sets
session
GET /api/v2/tools/exact-tld-fallback?keyword=X — (within session) Live-fallback polling for
exact-match enrichment

Response shapes (from JS parsing logic)

• search/bulk-search success: { status: "success", data: [ domainRow, ... ], data.pagination: { hasMore: bool } } or nested { data: { data: [...], pagination:
{...} } }.
• domainRow: { keyword, tldsCount, tldsActiveCount, extensions: [{extension, status}, ...], isLiveFallback, liveDomain, liveEvidence, checkedAt }.
• extension.status: one of active, parked, inactive, unknown.
• verify-captcha success: { success: true }.
• exact-tld-fallback success: { status: "success", data: { ux: { status, found, completed, queued, enabled }, exactResult: { keyword, tldsCount, tldsActiveCount,
extensions: [...] }, results: [...] } }.

reCAPTCHA flow (JS-derived)

1. Page loads, Google recaptcha script loads, window.onRecaptchaLoad fires.
2. window.__sldRecaptchaLoaded is truthy → window.initSldRecaptcha() runs → grecaptcha.render("recaptcha-container", { sitekey, size:"invisible", callback:
handleGoogleToken, "error-callback":..., "expired-callback":... }).
3. On API 401/403/429: grecaptcha.execute(widgetId) → Google returns token → handleGoogleToken(token) POSTs to /api/v1/client/verify-captcha → on {success:true}
sets sessionStorage.setItem("session_established","1") and re-runs loadDomains().
4. Retries capped at 1; after that shows "verificationFailedRefresh".
5. grecaptcha.reset(widgetId) after successful verify.

────────────────────────────────────

6. Where Things Stuck / Open Questions

6.1 — reCAPTCHA is the gate

The API path requires an invisible reCAPTCHA token per session. I could not complete the challenge in an automated context. The JS will attempt it and surface
"Verifying..." but I can't confirm whether the token is accepted without a valid Google-side challenge resolution. If the developer intends external/automated
access, reCAPTCHA is the blocker. Possible fixes the developer could consider:

• Issue API tokens/keys for programmatic access.
• Document whether the GET /sld?keyword= server-rendered path is the intended unauthenticated external interface and its rate limits.
• Lower or document the rate threshold that triggers CAPTCHA.

6.2 — MCP is not browser-accessible

The MCP endpoint is blocked by CORS from browser fetch, and requires an MCP client runtime to use. It's correctly designed for the ChatGPT/Claude connector paths
documented on /sld/ai, but it's not a general-purpose HTTP API. If the developer wants external scripts to call SLD Checker without going through ChatGPT/Claude,
they need a plain REST/HTTP API — and that's what /api/v2/tools/search and /api/v1/tools/bulk-search already are, modulo the CAPTCHA gate.

6.3 — Pagination / completeness of GET /sld?keyword=

Method Endpoint Auth/CAPTCHA Purpose
────── ────────────────────────────────────────────────────────────────────────────────────── ──────────────────────── ──────────────────────────────────
GET /sld?keyword=X None observed Server-rendered initial result
pi/v1/tools/bulk-search. The erver-rendered GET is single-keyword only. If bulk is importa t for exter(singlelkeyword) POST endpoint (and
itGETAPTCH/api/v2/tools/search?keyword=X&page=N&limit=20&matchType=...&status=...&extensions=... CAPTCHA on first call JS app single-keyword search,
per session paginated
POST /api/v1/tools/bulk-search CAPTCHA on first call Bulk search, JSON body
per session
POST /api/v1/client/verify-captcha — Submit reCAPTCHA token; sets
session
GET /api/v2/tools/exact-tld-fallback?keyword=X — (within session) Live-fallback polling for
exact-match enrichment
D>
Response shapes (from JS parsing logic)
• C
• search/bulk-search success: { status: "success", data: [ domainRow, ... ], data.pagination: { hasMore: bool } } or nested { data: { data: [...], pagination:
{...} } }.
• domainRow: { keyword, tldsCount, tldsActiveCount, extensions: [{extension, status}, ...], isLiveFallback, liveDomain, liveEvidence, checkedAt }.POST to
/mextension.status: one of active, parked, inactive, unknown. session; I did not test whether it blocks the GET).
verify-captcha success: { success: true }.
• exact-tld-fallback success: { status: "success", data: { ux: { status, found, completed, queued, enabled }, exactResult: { keyword, tldsCount, tldsActiveCount,
extensions: [...] }, results: [...] } }. (b) expos an API-token-based endpoint that byp sses reCAPTCHA for register d call rs.

reCAPTCHA flow (JS-derived)

1. Page loads, Google recaptcha script loads, window.onRecaptchaLoad fires.
2. window.__sldRecaptchaLoaded is truthy → window.initSldRecaptcha() runs → grecaptcha.render("recaptcha-container", { sitekey, size:"invisible", callback:
handleGoogleToken, "error-callback":..., "expired-callback":... }).hrome-backed) navigating to https://www.dnforum.com/sld/. HTTP tests were run from a Python
3. On API 401/403/429: grecaptcha.execute(widgetId) → Google returns token → handleGoogleToken(token) POSTs to /api/v1/client/verify-captcha → on {success:true}re
sets sessionStorage.setItem("session_established","1") and re-runs loadDomains().
4. Retries capped at 1; after that shows "verificationFailedRefresh".
5. grecaptcha.reset(widgetId) after successfuloverify. pagination on the GET, or a tempt a full
CAPTCHA-verify-then-API flow in the browser — say the word and I'll run it.
────────────────────────────────────

─ (6. Where Things Stuck / Open Questions:free │ 46.4k/524.3k │ [█░░░░░░░░░] 9% │ 9m 9s │ ◎ 80% │ ◷ 7.5s ─ DNForum SLD checker access and usability
❯ Ctrl+C to interrupt…
6.1 — reCAPTCHA is the gate

The API path requires an invisible reCAPTCHA token per session. I could not complete the challenge in an automated context. The JS will attempt it and surface
"Verifying..." but I can't confirm whether the token is accepted without a valid Google-side challenge resolution. If the developer intends external/automated
access, reCAPTCHA is the blocker. Possible fixes the developer could consider:

• Issue API tokens/keys for programmatic access.
• Document whether the GET /sld?keyword= server-rendered path is the intended unauthenticated external interface and its rate limits.
• Lower or document the rate threshold that triggers CAPTCHA.

6.2 — MCP is not browser-accessible

The MCP endpoint is blocked by CORS from browser fetch, and requires an MCP client runtime to use. It's correctly designed for the ChatGPT/Claude connector paths
documented on /sld/ai, but it's not a general-purpose HTTP API. If the developer wants external scripts to call SLD Checker without going through ChatGPT/Claude,
they need a plain REST/HTTP API — and that's what /api/v2/tools/search and /api/v1/tools/bulk-search already are, modulo the CAPTCHA gate.

6.3 — Pagination / completeness of GET /sld?keyword=

The server-rendered GET returns a populated table, but I did not determine how many rows it returns or whether it paginates via URL params (e.g. &page=2). The JS
app uses &limit=20&page=N against the API. The GET endpoint may be capped at a fixed number. If someone wants the full cross-TLD footprint for a keyword via the
simple GET path, that needs to be tested and documented.

6.4 — Status meanings

The tool labels domains as Active / Parked / Inactive. The "AI" page notes: "Inactive means SLD Checker did not identify the domain as active or parked. It does
not guarantee that the domain is available to register." I did not test the accuracy of this classification against a known sample.

6.5 — Bulk vs. single

Bulk mode POSTs to /api/v1/tools/bulk-search. The server-rendered GET is single-keyword only. If bulk is important for external callers, the POST endpoint (and
its CAPTCHA requirement) is the path, and it needs the same CAPTCHA treatment.

────────────────────────────────────

7. What Worked, Cleanly

The single most usable external path today is:

GET https://www.dnforum.com/sld?keyword=<WORD>

• No CAPTCHA required (verified for atlas).
• Returns a full HTML table with keyword, TLD count, active count, and per-extension status links.
• Parseable with any HTML parser.
• Works from a headless browser, a simple HTTP client, or even a curl one-liner (modulo any cookie/consent wall — the cookies modal is a separate POST to
/misc/cookies?update=1 that may need to be dismissed once per session; I did not test whether it blocks the GET).

If the developer wants external/automated access to be "comfortable," the cleanest move is to either (a) officially support and document the GET /sld?keyword=
path with its limits and rate policy, or (b) expose an API-token-based endpoint that bypasses reCAPTCHA for registered callers.

────────────────────────────────────

8. Reproducibility Notes

All browser tests were run via a real browser automation session (Chrome-backed) navigating to https://www.dnforum.com/sld/. HTTP tests were run from a Python
sandbox via urllib.request against https://sld.dnforum.com/mcp and https://www.dnforum.com/sld?keyword=atlas. The reCAPTCHA site key and all API endpoint URLs are
taken directly from the page's rendered JS and DOM — they are observable from outside and not inferred.

If you want me to extend the test — e.g. try more keywords via the GET path, test filter params, probe pagination on the GET, or attempt a full
CAPTCHA-verify-then-API flow in the browser — say the word and I'll run it.
 
@birajst, I have just run a test with "Solar Pro4" and it got stuck. Asked it to write a report.

:) #workinprogress

===

❯ write a detailed report I can copy/paste to the developer of this tool of your test results: the workflow you took and findings, and where you got stuck. provide
full information for the developer

┊ [showing live tail; omitted 1 lines / 51 chars]
atlas 675 477 .ac, .ac.cn, .ac.uk, ...

The table body `<tbody id="domain-table-body">` contains `<tr>` rows with four cells: keyword, TLD count, active count, and a comma-separated list of extension
links (each is an `<a href="https://keyword.tld">` tagged with a status CSS class: `text-success` = active, `text-warning` = parked, `text-danger` = inactive).
### What this means
This is the easiest external access path. No JavaScript required, no CAPTCHA triggered (at least for this single lookup), and the result is fully in the initial
HTML. An external caller can `GET /sld?keyword=WORD` and parse the table.
**Filtering** also works through the same mechanism — the JS app reads `filters` state and builds the API URL with `&matchType=...&status=...&extensions=...`.
The server-side `/sld?keyword=...` endpoint likely accepts the same params; I did not exhaustively test every filter combination but the form's GET action and
the JS `buildSingleSearchUrl()` both point at the same API shape, so URL params should carry through.
**Bulk mode** — the JS `POST /api/v1/tools/bulk-search` with `{"keywords":["a","b"],"page":1,"limit":50}` is the bulk path; the server-rendered GET is
single-keyword only.
### Known gap
The server-rendered page is a starting snapshot. The JS app adds pagination (infinite scroll, `loadDomains()` fetching `/api/v2/tools/search?page=2...`) and an
"exact TLD live fallback" polling loop that enriches results after the initial load. If you only use the GET, you get the initial page — likely the first 20
results (the JS default `limit=20` in `buildSingleSearchUrl`). To get all rows you'd need the API + pagination, which falls into Path B.
---
## 3. Path B — JS App + API + reCAPTCHA
### API endpoints discovered from JS (`/js/hmbiraj/sld/index.js`)
**Single search (GET):**

GET https://sld.dnforum.com/api/v2/tool...[&status=STATUS][&extensions=COMMA-SEPARATED]

- `matchType` values: `contains`, `starts_with`, `ends_with`, `exact` (from the filter UI — "Contains / Starts with / Ends with / Exact only")
- `status` values: `active`, `parked`, `inactive` (blank = any)
- `extensions`: comma-separated, e.g. `.com,.net,.org.uk`
- Response shape (from JS `extractDomainRows`/`extractPagination`): `{ status: "success", data: [...domain rows...], data.pagination: { hasMore: bool } }` — or
wrapped as `{ data: { data: [...], pagination: {...} } }`.
- A row looks like: `{ keyword, tldsCount, tldsActiveCount, extensions: [{extension, status}, ...], isLiveFallback, liveDomain, liveEvidence, checkedAt }`.
**Bulk search (POST):**

POST https://sld.dnforum.com/api/v1/tools/bulk-search
Content-Type: application/json
Body: { "keywords": ["kw1","kw2",...], "page": 1, "limit": 50 }

- Max 50 keywords (configurable via `data-bulk-limit` on `#sld-app`, default 50).
- Response same shape as single search.
**CAPTCHA verify (POST):**

POST https://sld.dnforum.com/api/v1/client/verify-captcha
Content-Type: application/json
Body: { "token": "RECAPTCHA_TOKEN" }

- Returns `{ success: true }` on valid token; sets a session flag in sessionStorage (`session_established = "1"`).
- After a successful verify, subsequent API calls within the session are allowed.
**Exact-TLD live fallback (GET, polled):**

GET https://sld.dnforum.com/api/v2/tools/exact-tld-fallback?keyword=ENCODED

- Pollable endpoint; the JS polls it after an initial search if `responseData.liveFallback === true`.
- Response: `{ status: "success", data: { ux: { status, found, completed, queued, enabled }, exactResult: { keyword, tldsCount, tldsActiveCount, extensions:
[...] }, results: [...] } }`.
- Status values: `idle`, `running`, `completed`, `disabled`, `failed`, `error`, `unavailable`, `saturated`.
### reCAPTCHA details
- Site key: `6Le-JbUsAAAAAIZZJZoqmg9kNdAY0tBru5NmeQoT`
- Widget: invisible, rendered into `#recaptcha-container` via `grecaptcha.render(...)` with `size: "invisible"`, `callback: handleGoogleToken`.
- Initialization: Google's `recaptcha__en.js` loads, calls `window.onRecaptchaLoad`, which calls `window.initSldRecaptcha()` if `window.__sldRecaptchaLoaded` is
set.
- Trigger: on API 401/403/429, the JS calls `grecaptcha.execute(recaptchaWidgetId)`, Google returns a token, `handleGoogleToken(token)` POSTs it to
`/api/v1/client/verify-captcha`, and on success sets the session and re-runs `loadDomains()`.
### What I observed in practice
1. Navigated to `/sld/`, page loads, reCAPTCHA badge present.
2. Typing into `#search-input` and clicking `#search-btn` correctly submits the form (JS `searchForm.addEventListener("submit", ...)`).
3. The table initially shows the header row only; the JS `loadDomains()` fires and the table populates via the API. On my first attempts the table stayed at
header-only — the search appeared to either be blocked by CAPTCHA (the JS would show "Verifying..." and then re-trigger) or the fetch was failing silently.
4. Using the direct URL `GET /sld?keyword=atlas` bypassed all of this and returned a fully populated table immediately — which strongly suggests the server
renders an initial result when keyword is in the query string, without needing the JS API path.
### Where I got stuck
I did not complete a full CAPTCHA → verify → API → paginate flow from scratch in the browser. The friction points:
- **No programmatic way to solve reCAPTCHA.** I can trigger `grecaptcha.execute()` from JS, get the token, and POST it — but the token is only valid if the
reCAPTCHA challenge actually passes on Google's side. In a headless/automated browser context, the invisible widget may fail or require a real user gesture. I
can't complete the challenge.
- **Session lifecycle unknown.** After verify, how long does the session last? The JS stores `session_established` in sessionStorage — that's browser-session
scoped, cleared on tab close. An external caller would need to re-verify every session (every new browser instance / every fresh tab). There's no API token
issued — just an opaque session.
- **Rate limits.** 429 responses trigger the CAPTCHA flow. The limits are not documented; repeated automated calls would burn through CAPTCHA retries (JS caps
retries at `MAX_CAPTCHA_RETRIES = 1`, then shows "verificationFailedRefresh").
### What would need to work for Path B to be "comfortable"
1. A registered API key or token that bypasses reCAPTCHA — none documented.
2. Or, accept that every new browser session requires a human to solve the invisible reCAPTCHA once, then automation can proceed until the session dies.
3. Or, the server-rendered `GET /sld?keyword=` path is the intended external interface and the JS app is just the interactive wrapper — in which case the limits
and pagination of that GET endpoint need to be documented.
---
## 4. Path C — MCP Endpoint `https://sld.dnforum.com/mcp`
### What I tried
- **Python urllib POST** with a proper MCP `initialize` JSON-RPC message → 403 / `{"error":"invalid_request"}` (after adding browser headers; first attempt was
403 Cloudflare `error code: 1010`).
- **Python urllib GET** → 405 Method Not Allowed.
- **Python urllib POST empty body** → 400 Bad Request.
- **Python urllib POST with JSON-RPC initialize as single line** → 400 Bad Request.
- **Browser `fetch()` from page JS** to `https://sld.dnforum.com/mcp` → `TypeError: Failed to fetch` (CORS — the browser blocks the cross-origin request).
### Analysis
MCP (Model Context Protocol) uses either:
- **streamable HTTP** — an initial POST establishes a session, then JSON-RPC messages flow bidirectionally over the same connection, or
- **SSE** — server-sent events for notifications.
Both require a persistent bidirectional transport. A simple `urllib.request.urlopen` or one-shot `fetch` cannot do this. The MCP client (Claude desktop, ChatGPT
plugin host) is designed to hold that connection open.
The 403/405/400 responses suggest the server is reachable but rejects improperly-formed MCP transport. The browser CORS failure (`Failed to fetch`) is the real
blocker for any in-browser use — the MCP endpoint does not send `Access-Control-Allow-Origin` for cross-origin browser `fetch`.
The documented "Use SLD Checker with AI" page (https://www.dnforum.com/sld/ai) describes:
- ChatGPT: install a Skill (`sld-checker-skill.zip`), which presumably runs the MCP connection server-side within ChatGPT's plugin runtime.
- Claude: add a custom connector with MCP URL `https://sld.dnforum.com/mcp`, no auth. Claude's connector runtime runs server-side and can hold the MCP stream.
**Conclusion:** The MCP endpoint is reachable and functional only from an MCP client runtime (Claude, ChatGPT plugin host) that runs server-side / same-origin.
It is **not** accessible from a browser JS context (CORS) or from a simple HTTP caller (transport mismatch). An external automation outside those platforms
cannot use it directly.
---
## 5. Technical Inventory for the Developer
### Page assets
| Resource | URL | Notes |
|---|---|---|
| SLD Checker page | `https://www.dnforum.com/sld/` | XenForo-based site, cookie wall, reCAPTCHA badge |
| App JS | `https://www.dnforum.com/js/hmbiraj/sld/index.js?v=f1c90bee` | Main app logic — full source readable |
| reCAPTCHA | `https://www.google.com/recaptcha/api.js?onload=onRecaptchaLoad&render=explicit` | Invisible widget |
| reCAPTCHA JS | `https://www.gstatic.com/recaptcha/releases/BnqMGSY_YP4cCmbNINHpJPkd/recaptcha__en.js` | Google's runtime |
### `#sld-app` dataset attributes (from JS `config` reading)
| Attribute | Default | Meaning |
|---|---|---|
| `data-api-url` | `https://sld.dnforum.com` | Base URL for all API calls |
| `data-recaptcha-site-key` | `6Le-JbUsAAAAAIZZJZoqmg9kNdAY0tBru5NmeQoT` | reCAPTCHA site key |
| `data-exact-tld-live-fallback-enabled` | `true` | Whether live fallback polling is on |
| `data-exact-tld-fallback-path` | `/api/v2/tools/exact-tld-fallback` | Fallback poll endpoint |
| `data-exact-tld-fallback-poll-interval` | `1000` (ms) | Poll interval |
| `data-bulk-limit` | `50` | Max bulk keywords |
### DOM elements of interest
| Element ID / selector | Role |
|---|---|
| `#sld-app` | Root; holds `data-*` config |
| `#search-input` | Single-keyword input (`name="keyword"`) |
| `#search-btn` | Submit button |
| `#bulk-mode-toggle` | Checkbox to switch to bulk mode |
| `#bulk-input` | Bulk keyword input (comma/Enter separated) |
| `#search-form` | `<form action="/sld/" method="get">` — submit triggers JS handler |
| `#domain-table-body` | `<tbody>` where results render |
| `#recaptcha-container` | Invisible reCAPTCHA widget target |
| `#advanced-filters-panel` | Filters UI (matchType, status, extensions) |
| `#extensions-modal` | Modal showing full extension list for a row |
### API summary
| Method | Endpoint | Auth/CAPTCHA | Purpose |
|---|---|---|---|
| GET | `/sld?keyword=X` | None observed | Server-rendered initial result (single keyword) |
| GET | `/api/v2/tools/search?keyword=X&page=N&limit=20&matchType=...&status=...&extensions=...` | CAPTCHA on first call per session | JS app single-keyword
search, paginated |
| POST | `/api/v1/tools/bulk-search` | CAPTCHA on first call per session | Bulk search, JSON body |
| POST | `/api/v1/client/verify-captcha` | — | Submit reCAPTCHA token; sets session |
| GET | `/api/v2/tools/exact-tld-fallback?keyword=X` | — (within session) | Live-fallback polling for exact-match enrichment |
### Response shapes (from JS parsing logic)
- **search/bulk-search success:** `{ status: "success", data: [ domainRow, ... ], data.pagination: { hasMore: bool } }` or nested `{ data: { data: [...],
pagination: {...} } }`.
- **domainRow:** `{ keyword, tldsCount, tldsActiveCount, extensions: [{extension, status}, ...], isLiveFallback, liveDomain, liveEvidence, checkedAt }`.
- **extension.status:** one of `active`, `parked`, `inactive`, `unknown`.
- **verify-captcha success:** `{ success: true }`.
- **exact-tld-fallback success:** `{ status: "success", data: { ux: { status, found, completed, queued, enabled }, exactResult: { keyword, tldsCount,
tldsActiveCount, extensions: [...] }, results: [...] } }`.
### reCAPTCHA flow (JS-derived)
1. Page loads, Google recaptcha script loads, `window.onRecaptchaLoad` fires.
2. `window.__sldRecaptchaLoaded` is truthy → `window.initSldRecaptcha()` runs → `grecaptcha.render("recaptcha-container", { sitekey, size:"invisible", callback:
handleGoogleToken, "error-callback":..., "expired-callback":... })`.
3. On API 401/403/429: `grecaptcha.execute(widgetId)` → Google returns token → `handleGoogleToken(token)` POSTs to `/api/v1/client/verify-captcha` → on
`{success:true}` sets `sessionStorage.setItem("session_established","1")` and re-runs `loadDomains()`.
4. Retries capped at 1; after that shows "verificationFailedRefresh".
5. `grecaptcha.reset(widgetId)` after successful verify.
## 6. Where Things Stuck / Open Questions
─────────────────────── ───────────────────────────────────────────────────────────────
#sld-app Root; holds data-* config
#search-input Single-keyword input (name="keyword")
#search-btn Submit button
#bulk-mode-toggle Checkbox to switch to bulk mode
#bulk-input Bulk keyword input (comma/Enter separated)
#search-form <form action="/sld/" method="get"> — submit triggers JS handler
#domain-table-body <tbody> where results render
#recaptcha-container Invisible reCAPTCHA widget target
#advanced-filters-panel Filters UI (matchType, status, extensions)
#extensions-modal Modal showing full extension list for a row

API summary

Method Endpoint Auth/CAPTCHA Purpose
────── ────────────────────────────────────────────────────────────────────────────────────── ──────────────────────── ──────────────────────────────────
GET /sld?keyword=X None observed Server-rendered initial result
(single keyword)
GET /api/v2/tools/search?keyword=X&page=N&limit=20&matchType=...&status=...&extensions=... CAPTCHA on first call JS app single-keyword search,
per session paginated
POST /api/v1/tools/bulk-search CAPTCHA on first call Bulk search, JSON body
per session
POST /api/v1/client/verify-captcha — Submit reCAPTCHA token; sets
session
GET /api/v2/tools/exact-tld-fallback?keyword=X — (within session) Live-fallback polling for
exact-match enrichment

Response shapes (from JS parsing logic)

• search/bulk-search success: { status: "success", data: [ domainRow, ... ], data.pagination: { hasMore: bool } } or nested { data: { data: [...], pagination:
{...} } }.
• domainRow: { keyword, tldsCount, tldsActiveCount, extensions: [{extension, status}, ...], isLiveFallback, liveDomain, liveEvidence, checkedAt }.
• extension.status: one of active, parked, inactive, unknown.
• verify-captcha success: { success: true }.
• exact-tld-fallback success: { status: "success", data: { ux: { status, found, completed, queued, enabled }, exactResult: { keyword, tldsCount, tldsActiveCount,
extensions: [...] }, results: [...] } }.

reCAPTCHA flow (JS-derived)

1. Page loads, Google recaptcha script loads, window.onRecaptchaLoad fires.
2. window.__sldRecaptchaLoaded is truthy → window.initSldRecaptcha() runs → grecaptcha.render("recaptcha-container", { sitekey, size:"invisible", callback:
handleGoogleToken, "error-callback":..., "expired-callback":... }).
3. On API 401/403/429: grecaptcha.execute(widgetId) → Google returns token → handleGoogleToken(token) POSTs to /api/v1/client/verify-captcha → on {success:true}
sets sessionStorage.setItem("session_established","1") and re-runs loadDomains().
4. Retries capped at 1; after that shows "verificationFailedRefresh".
5. grecaptcha.reset(widgetId) after successful verify.

────────────────────────────────────

6. Where Things Stuck / Open Questions

6.1 — reCAPTCHA is the gate

The API path requires an invisible reCAPTCHA token per session. I could not complete the challenge in an automated context. The JS will attempt it and surface
"Verifying..." but I can't confirm whether the token is accepted without a valid Google-side challenge resolution. If the developer intends external/automated
access, reCAPTCHA is the blocker. Possible fixes the developer could consider:

• Issue API tokens/keys for programmatic access.
• Document whether the GET /sld?keyword= server-rendered path is the intended unauthenticated external interface and its rate limits.
• Lower or document the rate threshold that triggers CAPTCHA.

6.2 — MCP is not browser-accessible

The MCP endpoint is blocked by CORS from browser fetch, and requires an MCP client runtime to use. It's correctly designed for the ChatGPT/Claude connector paths
documented on /sld/ai, but it's not a general-purpose HTTP API. If the developer wants external scripts to call SLD Checker without going through ChatGPT/Claude,
they need a plain REST/HTTP API — and that's what /api/v2/tools/search and /api/v1/tools/bulk-search already are, modulo the CAPTCHA gate.

6.3 — Pagination / completeness of GET /sld?keyword=

Method Endpoint Auth/CAPTCHA Purpose
────── ────────────────────────────────────────────────────────────────────────────────────── ──────────────────────── ──────────────────────────────────
GET /sld?keyword=X None observed Server-rendered initial result
pi/v1/tools/bulk-search. The erver-rendered GET is single-keyword only. If bulk is importa t for exter(singlelkeyword) POST endpoint (and
itGETAPTCH/api/v2/tools/search?keyword=X&page=N&limit=20&matchType=...&status=...&extensions=... CAPTCHA on first call JS app single-keyword search,
per session paginated
POST /api/v1/tools/bulk-search CAPTCHA on first call Bulk search, JSON body
per session
POST /api/v1/client/verify-captcha — Submit reCAPTCHA token; sets
session
GET /api/v2/tools/exact-tld-fallback?keyword=X — (within session) Live-fallback polling for
exact-match enrichment
D>
Response shapes (from JS parsing logic)
• C
• search/bulk-search success: { status: "success", data: [ domainRow, ... ], data.pagination: { hasMore: bool } } or nested { data: { data: [...], pagination:
{...} } }.
• domainRow: { keyword, tldsCount, tldsActiveCount, extensions: [{extension, status}, ...], isLiveFallback, liveDomain, liveEvidence, checkedAt }.POST to
/mextension.status: one of active, parked, inactive, unknown. session; I did not test whether it blocks the GET).
verify-captcha success: { success: true }.
• exact-tld-fallback success: { status: "success", data: { ux: { status, found, completed, queued, enabled }, exactResult: { keyword, tldsCount, tldsActiveCount,
extensions: [...] }, results: [...] } }. (b) expos an API-token-based endpoint that byp sses reCAPTCHA for register d call rs.

reCAPTCHA flow (JS-derived)

1. Page loads, Google recaptcha script loads, window.onRecaptchaLoad fires.
2. window.__sldRecaptchaLoaded is truthy → window.initSldRecaptcha() runs → grecaptcha.render("recaptcha-container", { sitekey, size:"invisible", callback:
handleGoogleToken, "error-callback":..., "expired-callback":... }).hrome-backed) navigating to https://www.dnforum.com/sld/. HTTP tests were run from a Python
3. On API 401/403/429: grecaptcha.execute(widgetId) → Google returns token → handleGoogleToken(token) POSTs to /api/v1/client/verify-captcha → on {success:true}re
sets sessionStorage.setItem("session_established","1") and re-runs loadDomains().
4. Retries capped at 1; after that shows "verificationFailedRefresh".
5. grecaptcha.reset(widgetId) after successfuloverify. pagination on the GET, or a tempt a full
CAPTCHA-verify-then-API flow in the browser — say the word and I'll run it.
────────────────────────────────────

─ (6. Where Things Stuck / Open Questions:free │ 46.4k/524.3k │ [█░░░░░░░░░] 9% │ 9m 9s │ ◎ 80% │ ◷ 7.5s ─ DNForum SLD checker access and usability
❯ Ctrl+C to interrupt…
6.1 — reCAPTCHA is the gate

The API path requires an invisible reCAPTCHA token per session. I could not complete the challenge in an automated context. The JS will attempt it and surface
"Verifying..." but I can't confirm whether the token is accepted without a valid Google-side challenge resolution. If the developer intends external/automated
access, reCAPTCHA is the blocker. Possible fixes the developer could consider:

• Issue API tokens/keys for programmatic access.
• Document whether the GET /sld?keyword= server-rendered path is the intended unauthenticated external interface and its rate limits.
• Lower or document the rate threshold that triggers CAPTCHA.

6.2 — MCP is not browser-accessible

The MCP endpoint is blocked by CORS from browser fetch, and requires an MCP client runtime to use. It's correctly designed for the ChatGPT/Claude connector paths
documented on /sld/ai, but it's not a general-purpose HTTP API. If the developer wants external scripts to call SLD Checker without going through ChatGPT/Claude,
they need a plain REST/HTTP API — and that's what /api/v2/tools/search and /api/v1/tools/bulk-search already are, modulo the CAPTCHA gate.

6.3 — Pagination / completeness of GET /sld?keyword=

The server-rendered GET returns a populated table, but I did not determine how many rows it returns or whether it paginates via URL params (e.g. &page=2). The JS
app uses &limit=20&page=N against the API. The GET endpoint may be capped at a fixed number. If someone wants the full cross-TLD footprint for a keyword via the
simple GET path, that needs to be tested and documented.

6.4 — Status meanings

The tool labels domains as Active / Parked / Inactive. The "AI" page notes: "Inactive means SLD Checker did not identify the domain as active or parked. It does
not guarantee that the domain is available to register." I did not test the accuracy of this classification against a known sample.

6.5 — Bulk vs. single

Bulk mode POSTs to /api/v1/tools/bulk-search. The server-rendered GET is single-keyword only. If bulk is important for external callers, the POST endpoint (and
its CAPTCHA requirement) is the path, and it needs the same CAPTCHA treatment.

────────────────────────────────────

7. What Worked, Cleanly

The single most usable external path today is:

GET https://www.dnforum.com/sld?keyword=<WORD>

• No CAPTCHA required (verified for atlas).
• Returns a full HTML table with keyword, TLD count, active count, and per-extension status links.
• Parseable with any HTML parser.
• Works from a headless browser, a simple HTTP client, or even a curl one-liner (modulo any cookie/consent wall — the cookies modal is a separate POST to
/misc/cookies?update=1 that may need to be dismissed once per session; I did not test whether it blocks the GET).

If the developer wants external/automated access to be "comfortable," the cleanest move is to either (a) officially support and document the GET /sld?keyword=
path with its limits and rate policy, or (b) expose an API-token-based endpoint that bypasses reCAPTCHA for registered callers.

────────────────────────────────────

8. Reproducibility Notes

All browser tests were run via a real browser automation session (Chrome-backed) navigating to https://www.dnforum.com/sld/. HTTP tests were run from a Python
sandbox via urllib.request against https://sld.dnforum.com/mcp and https://www.dnforum.com/sld?keyword=atlas. The reCAPTCHA site key and all API endpoint URLs are
taken directly from the page's rendered JS and DOM — they are observable from outside and not inferred.

If you want me to extend the test — e.g. try more keywords via the GET path, test filter params, probe pagination on the GET, or attempt a full
CAPTCHA-verify-then-API flow in the browser — say the word and I'll run it.

@DN AI summarize the findings of this last test
 
Summary of the Solar Pro4 test

The test found that the SLD Checker is largely machine-readable, but there are two very different access paths:

  • The simple single-keyword page works well: using `/sld?keyword=WORD` returned a populated HTML table for the tested keyword (“atlas”), without JavaScript or CAPTCHA being required in that test. The result includes the keyword, total TLD count, active count, and extension-level status links. This appears to be the easiest path for an agent or external parser.
  • The interactive/API path is less automation-friendly: the JavaScript search API, bulk search, pagination, and live exact-TLD fallback are protected by invisible reCAPTCHA when the session is challenged, rate-limited, or unauthenticated. Solar Pro4 could inspect the flow, but could not complete a reliable CAPTCHA verification cycle in an automated browser environment.
  • Bulk search is available but gated: bulk requests use a POST endpoint and accept up to 50 keywords per request, but appear subject to the same CAPTCHA/session restriction. That makes it less suitable for unattended third-party automation.
  • MCP is intended for proper MCP clients, not browser scripts: the MCP endpoint could not be used through normal browser `fetch()` because of CORS, nor through basic one-shot HTTP requests. The conclusion was that it should work through supported server-side MCP runtimes, such as the documented ChatGPT/Claude connector route, rather than as a general public REST endpoint.
  • Important unknowns remain: the test did not establish the simple GET endpoint’s rate limits, full pagination behavior, filter support, or whether it returns every matching extension. It also did not validate the accuracy of Active / Parked / Inactive classifications against a known sample.

Bottom line: for a single keyword, the server-rendered GET page appears to be a clean and useful machine-friendly entry point. For reliable bulk, pagination, or fully automated API use, reCAPTCHA is currently the main obstacle.

Suggested improvements from the test:

  • Officially document the GET endpoint, supported parameters, pagination, and rate limits.
  • Offer API keys/tokens for approved programmatic users, so legitimate agents do not need to solve reCAPTCHA.
  • Keep MCP as the AI-client integration path, but provide a documented REST option for external scripts and bulk workflows.

Also, the tool itself did not appear to fail while retrieving data. It got stuck writing an extremely long technical report, with duplicated sections and an unfinished live output.
 
I got this. I havent included steps for hermes agent yet and will update it as soon as possible. however setting up in Hermes agent is very easy. all you have to do is:
1. Download SLD checker skill.
2. Go to Hermes Agent Desktop and upload SLD Checker Skill.
3. Send this prompt:
Markdown (GitHub flavored):
Install this skill and connect the SLD Checker MCP endpoint.
 
I got this. I havent included steps for hermes agent yet and will update it as soon as possible. however setting up in Hermes agent is very easy. all you have to do is:
1. Download SLD checker skill.
2. Go to Hermes Agent Desktop and upload SLD Checker Skill.
3. Send this prompt:
Markdown (GitHub flavored):
Install this skill and connect the SLD Checker MCP endpoint.

:) we should not tell this to Hermes Agents - they should understand this immediately themselves. Thank you
 
Appreciate you including the misses alongside the wins, Helmuts. For the next comparison, it would be cool to throw in a handful of fresh drops or names registered just a couple of days ago to see how fast each platform updates its index. That would give a much better feel for data freshness rather than just measuring raw database size.
 
:) we should not tell this to Hermes Agents - they should understand this immediately themselves. Thank you
We had to give prompt because sld checker skill was not ready for auto install so I didn't mentioned hermes agent for sld checker with ai. however I have figured out the solution and updated sld checker skill and we are able to access sld checker just by providing skill zip file.
 
Back
Top Bottom