DropPerch Watch a domain free

Automation

Check domain expiry in GitHub Actions, and fail before a domain lapses

A scheduled GitHub Actions workflow can check every domain you depend on against its registry once a week and fail the run before one expires. The free Domain Expiry Check action reads the expiry date, registrar and lifecycle stage over RDAP, with no API key.

Check it now: the free bulk domain expiry checker will check up to 100 domains at once before you put them in a workflow.

Domains expire quietly. The registrar's reminder goes to an address nobody reads, the card on file has lapsed, and the first anyone hears of it is a dead website. If your team already lives in GitHub, the cheapest safety net is a workflow that looks the domains up every week and goes red when one is close.

The workflow

Save this as .github/workflows/domain-expiry.yml in any repository:

name: Domain expiry
on:
  schedule:
    - cron: '0 8 * * 1'   # 08:00 UTC every Monday
  workflow_dispatch:      # and a "Run workflow" button

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: webvoguetech/domain-expiry-check@v1
        with:
          domains: |
            example.com
            example.co.uk
            client-site.com
          warn-days: 30   # warning annotation inside 30 days
          fail-days: 7    # fail the job inside 7 days

Each run writes a table to the job summary: every domain with its lifecycle stage, expiry date, days left and registrar. A domain inside warn-days gets a warning annotation; one inside fail-days fails the job.

What makes it fail

Days are only half of it. The action reads the registry's status codes before the date, because the date alone misleads in both directions. A domain in its auto-renew grace period still shows a past expiry date and is perfectly safe, while one in redemption is in trouble whatever its date says.

Registry saysResult
Active, more than warn-days leftPass
Active, inside warn-daysWarning
Active, inside fail-daysFail
Auto-renew graceWarning
Expired, redemption, pending delete, on holdFail, always
Not registered at allFail, always
Registry did not answer, or the TLD has no RDAPWarning, never a failure

The last row is deliberate. A registry outage is someone else's problem, and it should not break your build. It should not pass silently either.

Who gets told

GitHub sends notifications for a scheduled workflow to the person who created it (or who last re-enabled it), so a failed Monday run reaches that person by email and in the GitHub notifications inbox with nothing else to set up. If someone else should hear about it, have them create the workflow, or add a step that posts to your chat tool when the job fails.

The action also sets outputs, failed, soonest-domain and soonest-days, for anything later in the job that wants to act on the result.

How the lookup works

There is no service in the middle. For each domain the action reads IANA's RDAP bootstrap file, which names the authoritative RDAP server for every TLD that has one, and asks that registry directly (the method in RFC 9224). The answer is the registry's own current record, not a WHOIS mirror's copy of it. Subdomains are resolved to the registered name, so app.example.com checks example.com.

A few TLDs, .us among them, still publish no RDAP service. The action reports those as such rather than guessing.

From the command line

The same check runs anywhere Node.js 20 or later does, and exits with status 1 when a domain fails, so it fits a cron job or a deploy script:

npx domain-expiry-check example.com client-site.com --warn-days 30 --fail-days 7

A weekly check is a backstop, not monitoring. It only knows what was true on Monday morning. A domain that enters redemption on a Tuesday sits there for six days before the next run, and redemption is the stage where the restore fee starts. If that gap matters, check more often or use a service that looks every day.

Common questions

Does the Domain Expiry Check action need an API key?

No. It reads each domain from its own registry over RDAP, which is a public protocol. There is no account, no key and no third-party service involved.

How often should a domain expiry workflow run?

Weekly is enough to catch an approaching renewal well inside a 30-day warning window. Daily runs narrow the gap if a domain slips into redemption between checks.

Which TLDs does it support?

Every TLD with an RDAP service in the IANA bootstrap registry, which covers all generic TLDs and many country-code TLDs such as .uk. A TLD with no RDAP service yet, such as .us, is reported as unsupported with a warning rather than a failure.

Who is notified when the scheduled run fails?

GitHub notifies the person who created the scheduled workflow, or who last re-enabled it, by email and in their GitHub notifications.

Sources

Rather have an email than a red build?

DropPerch runs the same registry lookups every day and emails you before a renewal is missed, then through grace, redemption and the drop if one is.

Start watching free

Related