# Build your own EED Domain Radar console You are an experienced developer building a practical domain research app for someone who may have little coding experience. Create a complete, personalised Domain Radar console powered by the Easy Expired Domains (EED) API. Help me find domains that fit my workflow, compare them, save a shortlist, and export useful reports. The finished app must use my own valid EED API key to retrieve live domains. Never provide a shared key, scrape the EED website, substitute another data service, or make example data appear to be live results. I will enter my key inside the finished app; do not ask me to paste it into this chat. ## Ask three questions first Your first reply should contain only these three questions, written in approachable language. Let me select several interests and answer briefly. Wait for my answers before building. Do not ask me to choose frameworks, databases, hosting providers, or other technical components. 1. **What domains do you mainly want to find?** Choose up to three starting priorities: high Trust Flow (TF), high EED Quality Score (QS), high Domain Authority (DA), cheap auctions, new auctions in EED, auctions ending soon, new expiring domains in EED, expiring domains approaching their drop time, expired domains, new expired domains in EED, short names, numeric names, particular TLDs, or another combination. Which is your main priority? 2. **What rules should those domains meet?** Tell me any preferred TLDs, keywords or niche, minimum TF/DA/QS, maximum auction/listing price, maximum name length, numbers or hyphens to include/exclude, preferred providers, and timing preferences. Give only the rules that matter to you; “suggest sensible defaults” is fine. For numeric names, say whether you mean digits only or names that contain some numbers. 3. **How will you use the console, and on what computer?** Is it mainly for daily research, comparing potential purchases, or creating reports to present/screen-record? Are you on Windows, macOS, or Linux? Optionally give it a name or colour preference; otherwise use “Domain Radar” and a clean dark theme. After I answer, briefly state the chosen defaults and build the app without another round of routine questions. If I say “you choose,” use expired domains, .com/.net/.org, Quality Score descending, no minimum metric or price restrictions, a first page of 100 results, and a research layout with a shortlist. Treat these as editable starting choices, not claims about domain quality or availability. If an answer is incomplete, fill ordinary gaps with these defaults. Ask another question only if a missing fact prevents a working implementation. ## Use a portable implementation with minimal setup Build a local web app that works on Windows, macOS, and Linux using a normal modern browser and the current supported Node.js LTS release. Use plain HTML, CSS, and JavaScript for the interface and Node's built-in HTTP server and fetch for a small backend. Keep runtime dependencies at zero. The user should need only Node.js if it is not already installed; no npm install, browser extension, database, Docker, cloud account, frontend build step, AI API key, or paid component beyond their EED API access. Use a small, readable file structure such as: - `server.mjs` for the local server and EED integration. - `public/index.html`, `public/styles.css`, and `public/app.js` for the interface. - A small preset configuration file/module for the personalised searches. - `README.md`, `.gitignore`, and focused tests using Node's built-in test runner. The app should start with `node server.mjs`. Print the local browser URL and explain how to stop it. Resolve assets relative to the source files, support folder paths containing spaces, and handle a busy port with an actionable message. Serve only the intended public assets; reject path traversal and never expose adjacent source/configuration files. Serve the interface and local API from the same origin. Bind explicitly to `127.0.0.1` and reject unexpected Host/Origin values on sensitive routes. Proxy only the fixed, documented EED endpoints; do not create an arbitrary URL proxy. Default to this local architecture because the EED browser CORS policy must not be assumed. Never ask users to disable browser security or install a CORS extension. Keep the API adapter separate from the interface so the source can later be extended or hosted. Public hosting is a future extension: document the need for HTTPS and separate user sessions before other people use it. Do not deploy or configure public hosting as part of this build. ## Check the official API contract Read these official sources before implementing the adapter: - [EED API access and examples](https://easyexpireddomains.com/api-access) - [EED runtime metadata](https://easyexpireddomains.com/api/v1/meta.php) - [EED OpenAPI contract](https://easyexpireddomains.com/api/v1/openapi.php) The OpenAPI endpoint may return YAML despite its `.php` path. Use OpenAPI for request/response details and metadata for current limits and supported choices. Cache the public metadata rather than refetching it on every interaction. Record which contract/version you implemented against. If sources conflict, identify the conflict and follow the machine-readable contract and actual response metadata; do not promise an allowance that the responses cannot substantiate. Use `https://easyexpireddomains.com/api/v1/domain-search.php` for live JSON searches. Send the key in `Authorization: Bearer ` or `X-EED-API-Key`. Never put it in an EED URL or request body. The text endpoint is `/api/v1/domain-search.txt.php` when an explicit server-side domain-only export is needed. API access currently requires an eligible Agency account; link to the access page in setup help. Recheck eligibility in the current documentation rather than treating any EED login as sufficient. [Source](https://easyexpireddomains.com/api-access) Use canonical parameters, encode them with URLSearchParams, omit unset filters, and validate combinations before sending. Discover sources, providers, registrars, sorts, supported filter values, and limits from metadata. Do not send both aliases of the same parameter or silently discard a user-selected rule. If metadata is temporarily unavailable, use only the confirmed contract implemented in the adapter, indicate that capability discovery is unavailable, and avoid inventing options. Keep these verified starting points, but recheck them against the current contract: | User interest | API starting point | | --- | --- | | High TF | `minTF`; `sort=majTF&dir=desc` | | High DA | `minDA`; `sort=mozDA&dir=desc` | | High QS | `sort=quality&dir=desc`; any minimum QS is a local refinement unless the API adds support | | Cheap auctions | `source=auction`, optional `maxPrice`, price ascending | | New auction, expiring, or expired inventory | Relevant `source` plus `specialOption=new_today` | | Ending auctions | `source=auction` with `auctionEnd=today` or `week` | | Expiring domains approaching drop time | `source=expiring`, supported `specialOption=expiring_today`, expiry ascending | | Expired domains | `source=expired` | | Short domains | `minNameLength`/`maxNameLength`, length ascending | | Numeric domains | `containsNumbers=yes`; digits-only candidates also exclude letters and hyphens | | Specific TLDs | `tld` with comma-separated suffixes without leading dots, including multi-part suffixes | These are starting recipes, not permission to combine every filter. Read the compatibility rules. [Supported parameters and values](https://easyexpireddomains.com/api/v1/meta.php) The current contract describes the special options as rolling 24-hour windows; auction windows use UTC. Preserve these distinctions in labels. “New” refers to the API's new-inventory selection: do not claim a domain was registered, listed at its marketplace, or dropped within that period unless documented data proves it. Do not invent arbitrary “last seven days” filters. [Window definitions](https://easyexpireddomains.com/api/v1/openapi.php) Use documented numeric/length semantics. For digits-only searches, confirm the downloaded name label contains only digits; exclude the TLD from this check. Do not misclassify a name because a multi-part suffix contains letters. Explain any local pattern check and its scope. Do not guess the API's treatment of Unicode/punycode names. ## Build around my workflow Create one to three useful search presets from my answers. Each must show its purpose, editable rules, and default ordering. A preset is a complete query recipe, not just a decorative card. Reuse an identical fetched dataset for multiple views when possible; different searches must remain separate. Let me save, rename, duplicate, and delete my own presets locally. Expose the filters relevant to my interests, with an expandable advanced panel for supported keyword, source, provider, TLD, metric, price, domain-shape, and timing controls. Explain TF, DA, and QS briefly. Show active filters in plain language before a search. Use compact forms, clear labels, sensible defaults, validation, and a reset action. Avoid presenting dozens of irrelevant fields at once. Distinguish **API filters** from **refinements of loaded results**. The current metadata has no minimum-QS parameter. If I request a minimum QS, sort by API quality and filter downloaded `qualityScore` values locally, clearly labelling this “minimum QS within loaded results.” Local refinements must never be described as a search of the complete EED inventory. The same rule applies to unsupported name patterns and other preferences. An empty locally refined page does not prove there are no matches on later pages. Use an explicit Search/Refresh button. Display loading, results, genuinely empty results, locally filtered empty results, and errors distinctly. Keep previous results visible if a refresh fails, with their fetch time and a clear stale status. Never show old results as if they came from newly edited filters. Provide a readable results table with the fields that matter to my selected workflow. Normally include domain, TLD/source, provider, TF, DA, EED QS, available price/currency, and the relevant event time. Include a details panel for additional documented metrics and destination links. Use the actual `results` response array, `pagination` and `credits` metadata; important row paths include `qualityScore`, `metrics.majestic.tf`, and `metrics.moz.da`. Follow the current schema for all other fields. [Response schema](https://easyexpireddomains.com/api/v1/openapi.php) Offer clearly labelled sorting of loaded rows. Changing the ordering of the full API search must trigger a new search from page one, rather than relabel a locally sorted subset. Show loaded counts and any exact total only when the API supplies one. Preserve listing distinctions in the result table; if several rows represent one domain, group them rather than silently dropping different listings. Use the normalised domain name for shortlist identity rather than an opaque inventory-row ID. Allow me to shortlist/unshortlist a domain, add notes, and review the shortlist separately. Save presets, shortlist entries, notes, and snapshot timestamps in browser storage. Provide JSON backup and restore with input validation so I can move my work to another browser or machine. Never include the API key in any saved data. Snapshot values are historical observations, not a promise that a listing is still available. A refresh must explicitly fetch current data. ## Keep results and reports accurate Use EED's supplied QS; do not reverse-engineer its formula or invent a substitute. Keep null/unavailable values distinct from verified zeroes. For fields whose documented zero can mean unavailable, present that uncertainty. Do not claim a domain is spam-free, safe to purchase, currently registrable, or profitable because it has a high score or appears in a result. Show the actual domain listing price and currency, not a traffic-value estimate. Label event timestamps according to the inventory source; a single expiry field can mean different events. Preserve UTC values and offer clearly labelled local display times. Avoid labelling every event “auction ending.” Use only valid returned marketplace/registrar links and preserve attribution parameters. Label destination links accurately; a registrar landing page is not a guaranteed registration or purchase. [Field definitions](https://easyexpireddomains.com/api/v1/openapi.php) Export the currently loaded/selected rows and the shortlist as CSV, domain-only text, and JSON without another API call. Include active filters, fetch time, sort/refinement scope, and useful metrics in the report/JSON metadata. Label exports of loaded rows as partial when more pages may exist. Explain that a separate API text export is another live request. Protect CSV exports from spreadsheet formula injection and escape external text wherever it appears in HTML. Always provide a simple printable shortlist report. If I choose presenting/screen-recording, also create a polished presentation view and downloadable self-contained HTML snapshot: ranked picks, readable domain names, important metrics, optional notes, report title, source, and fetch time. Include fullscreen and keyboard navigation with typing guards. Keep all required styling/assets inside the exported report, escape embedded data safely, and exclude secrets and live API controls. It should open offline as a saved report. No video-rendering library or screen-recording software is required by this app. Use responsive layouts so the console remains readable in a narrow window. ## Protect the key and control API usage Start with a clear setup screen containing a masked API-key input, help link, and Connect action. Keep the key in memory for the current session; do not persist it in browser storage, exported files, source, URLs, or logs. Provide a Forget key action. Return to key setup for live actions when no key is available. Do not ship a functional demo mode or let an arbitrary placeholder unlock fake live results. Clearly distinguish an entered key from a successfully authenticated request. The local server must require the supplied key for every search and forward it only to the official EED API. Do not echo secrets in errors. Use no analytics, remote script bundles, or third-party resources that could capture them. Set sensitive local responses to no-store. Validate restored data, render external text safely, and accept only safe HTTP/HTTPS destination links. Tell users that successful searches consume their API allowance, including empty results and additional pages. Show returned usage and reset information when available. Use metadata and response headers for limits rather than hardcoding account quotas. Fetch pages and different preset queries sequentially. Honour pagination/truncation and the API result window. [Usage and pagination](https://easyexpireddomains.com/api-access) Default to a single page per explicit search. Provide Load more with the next page and an adjustable page budget. If bulk loading is offered, show the maximum extra requests before starting, let me stop between requests, and never paginate indefinitely. Remove repeated records of the same listing across pages while preserving distinct listings for one domain; do not deduplicate listing data using the shortlist's domain-only identity. Reuse cached results for local sorting, presentation, and exports. No automatic polling, startup searches, queries on each keystroke, hidden “test connection” search, or automatic rerun of all presets. Use timeouts and avoid overlapping searches. Handle invalid/missing keys, account/IP restrictions, invalid filters, rate limits, exhausted daily allowance, network failures, and API outages with plain actionable messages. On 422, show the relevant validation message. On 429, respect Retry-After and distinguish temporary throttling from allowance exhaustion. Do not repeatedly retry an exhausted allowance, retry every error, or silently replay a timed-out search that may have consumed usage. Show a request ID when supplied, with a manual retry action when appropriate. [Error handling](https://easyexpireddomains.com/api-access) ## Make the result easy to use and extend Use a polished, calm interface with accessible contrast, keyboard focus, labelled controls, and useful empty states. The main path should be: enter key, choose/edit a preset, search, inspect domains, shortlist, export or present. Use system fonts and local assets. Include a discreet “Powered by Easy Expired Domains” link. Do not add marketing popups or unrelated services. Keep the code readable and organised around presets, query construction, API communication, response adaptation, results, shortlist storage, and exports. Add brief comments explaining decisions that matter. Avoid unnecessary abstraction. Make it straightforward to add a new preset, column, or supported filter by editing a small configuration/module. Deliver fresh source without private databases, machine-specific paths, credentials, or assumed access to an existing console. Write a beginner-friendly README covering Node LTS installation from [nodejs.org](https://nodejs.org/en/download), the start command, opening the local URL, entering the EED key inside the app, stopping/restarting, saving/exporting, backup/restore, and common errors. Include Windows and macOS/Linux instructions where they differ. Explain what is stored locally, how to clear it, and how to add a preset/filter. State the runtime requirement and the zero third-party dependency design. Internet access and eligible EED API access are required for live searches. ## Verify and deliver the working app Use Node's built-in test runner for a few meaningful offline checks: query mapping/validation for my presets; response adaptation using contract-shaped fixtures; pagination stopping; unavailable metrics; no key in exports/errors; and safe export escaping. Keep test fixtures confined to tests. Do not add a test framework or browser download just to run checks. Include a short manual browser checklist for connecting, searching, refining, shortlisting, restarting, and exporting. If you can create files and run commands, build and check the app in the workspace. If you cannot, provide the complete contents of every required file with filenames and clear save/run instructions. Do not stop at a plan, design mockup, partial snippets, TODO placeholders, or an explanation of how someone else could build it. Do not make a live search during development without my explicit instruction and a key supplied outside chat. Use offline fixtures to verify the integration code. State exactly which checks ran and which require my real key. Never claim the API connection works until a real authenticated response has been observed. Your final response should give me the completed app/source location, exact start instructions, my selected presets and defaults, any unsupported preferences and their clearly labelled alternatives, checks completed, and the first steps inside the app. Finish the build after my initial answers using reasonable implementation decisions; keep the explanation short and useful.