A simple HTTP daemon that watches WHOIS/RDAP responses for domains. Every response is parsed and stored. It can be used to track domains that have expired or are close to expiring.
It is intended to be used with CLI HTTP clients such as cURL on Linux or Invoke-RestMethod in Windows PowerShell. It also includes a browser UI.
The daemon is built in C# with AOT compilation. The UI is written in solidjs and compiled to a single .html file.
-
automatic resolution of the WHOIS/RDAP server for a given TLD
-
automatic WHOIS/RDAP queries for watched domains
-
generation of a watched-domain list sorted by availability, then by expiration timestamp
-
daemon API designed for
cURL/PowerShellas the preferred control interface -
simple single .html file UI written in solidjs
-
every raw response is stored in a sqlite db for further processing
-
AOT compilation: no ORM - raw
System.Datais used to support AOT compilation, with a custom HTTP server written from scratch
To build the docker container, use docker build https://github.com/malciin/domain-watcher.git -t domain-watcher:1.0
Then run docker run --rm -it -p XYZ:80 -v domain-watcher.db:/app/sqlite.db domain-watcher:1.0, where XYZ is the port number.
Run ./DomainsWatcher.Cli --port XYZ, where XYZ is the port number.
If you do not want to provide --port XYZ every time, create a settings.yaml file. Check settings.Reference.yaml to see the available options.
(assume port to be 8051)
| PowerShell | cURL | Description |
|---|---|---|
Invoke-RestMethod http://localhost:8051 |
curl localhost:8051 |
Gets watched domain statuses |
Invoke-RestMethod http://localhost:8051/google.com |
curl localhost:8051/google.com |
Gets the RDAP/WHOIS response for a domain. If a recent response is available, it returns the cached one. It does not change the domain's watch status |
Invoke-RestMethod http://localhost:8051/google.com/f |
curl localhost:8051/google.com/f |
Gets a fresh RDAP/WHOIS response for any domain. It does not change the domain's watch status |
Invoke-RestMethod http://localhost:8051 -Method 'POST' -Body 'google.com' |
curl -d "google.com" localhost:8051 |
Watches a domain and returns its status |
Invoke-RestMethod http://localhost:8051 -Method 'DELETE' -Body 'google.com' |
curl -X DELETE -d "google.com" localhost:8051 |
Stops watching a domain |
Invoke-RestMethod http://localhost:8051/queue |
curl localhost:8051/queue |
Gets the watched-domain queue status, including when each watched domain will be queried |
Invoke-RestMethod http://localhost:8051/s/*.dev |
curl localhost:8051/s/*.dev |
Search endpoint. Returns the status of watched domains matching the given filter. In this example, it returns all watched domains for the .dev TLD. More information is available in the Searching section |
Examples:
# Example usage
~$ curl localhost:8051
| Domain | Status | Expiration | Queried |
-----------------------------------------------------------------
| some-untaken-domain.com | Available | | 1m 17s ago |
| youtube.com | Taken | 1mo 5d | 1m 23s ago |
| google.net | Taken | 2mo 4d | 1m 11s ago |
| twitch.tv | Taken | 5mo 4h | 2d 23h ago |
| microsoft.com | Taken | 1y 3mo | 1m 6s ago |
| google.com | Taken | 4y 8mo | 1m 28s ago |
~$ curl localhost:8051/youtube.com
Domain Name: YOUTUBE.COM
Registry Domain ID: 142504053_DOMAIN_COM-VRSN
Registrar WHOIS Server: whois.markmonitor.com
Registrar URL: http://www.markmonitor.com
Updated Date: 2023-01-14T09:25:19Z
Creation Date: 2005-02-15T05:13:12Z
Registry Expiry Date: 2024-02-15T05:13:12Z
# remaining data
~$ curl localhost:8051/queue
7 domains enqueued.
Query intervals:
Domain taken 7d
Domain taken but expiration hidden 2d
Domain free 1d
Missing parser 7d
Base errror retry delay 7d
| Domain | Next query | Last query |
-----------------------------------------------------
| some-untaken-domain.com | 23h 55m | 4m 49s |
| twitch.tv | 4d 22m | 2d 23h |
| google.com | 6d 23h | 5m |
| youtube.com | 6d 23h | 4m 55s |
| google.net | 6d 23h | 4m 42s |
| microsoft.com | 6d 23h | 4m 38s |
~$ curl -d "dot.net" localhost:8051
dot.net watched! Status: Taken for 1y 15d (2025-01-25 05:00)
~$ curl localhost:8051/s/*.net
| Domain | Status | Expiration | Queried |
--------------------------------------------------
| google.net | Taken | 2mo 4d | 44m 27s ago |
| dot.net | Taken | 1y 15d | 11s ago |There is a simple built-in browser UI written in solidjs. Open http://localhost:8051 (or the port your daemon is listening on) in your browser to see it.
The /s/{filter} endpoint searches through watched domains. Filters can contain letters, digits, *, or +.
* means a string of any length, and + means exactly one character. If the query does not contain * or +, it matches any domain containing the query substring. Example filters:
| Url | Result |
|---|---|
localhost/s/*.dev |
Domains that end with .dev |
localhost/s/*.++ |
Domains with exactly a two-letter TLD (pl, eu, etc.) |
localhost/s/*.+++ |
Domains with exactly a three-letter TLD |
localhost/s/google.* |
Google domains |
localhost/s/google* |
Domains that begin with the string google |
localhost/s/*.*** |
Domains with a TLD of three or more letters |
localhost/s/+++.* |
3-letter domains (without TLD) |
localhost/s/+++*.* |
4+ letter domains (without TLD) |
localhost/s/gg |
any domain containing the string gg |
The built-in HTTP server is not intended to face untrusted network traffic.

