Revised

Find newly listed expired domains

Poll the Revised API for expired domains added since your last run with sort=latest, on any plan — and how the new-listing delay, batch timestamps and availability stamps affect what you see.

New names enter the directory every time the discovery pipeline runs. This guide polls for them: list the directory newest first, stop at the last listing you already have, and repeat on a schedule. It works on every plan, and it is a different job from Incremental sync, which tracks changes to listings you already hold.

Newest first

sort=latest orders the directory by discovered_at, newest first, tie-broken by listing id. discovered_at is written once, when the listing entered the directory, and never changes — which is what makes the ordering safe to page with a cursor.

bash
curl -s -G https://getrevised.com/api/v1/domains \
  -H "Authorization: Bearer $REVISED_API_KEY" \
  -d sort=latest \
  -d tier=open \
  -d limit=20

discovered_at is a fact about the directory, not the domain. It is neither the date the name expired nor its original registration date.

Your plan decides what “new” means

A new listing is hidden from each plan for a set time after it enters the directory:

PlanNew listings visible after
Free7 days
Pro1 day
BusinessImmediately

Until then it is not in your results at all, and GET /api/v1/domains/{id} for it returns 404. On Free, the newest listing you can see is at least a week old. See Plans and limits.

Poll for what you have not seen

Listings arrive in batches, and every listing in a batch can share one discovered_at. So do not stop at the first timestamp equal to your last run’s — stop at the first one older than it, and skip ids you already hold.

python
import os
import time

import requests

URL = "https://getrevised.com/api/v1/domains"
session = requests.Session()
session.headers["Authorization"] = f"Bearer {os.environ['REVISED_API_KEY']}"


def new_listings(last_seen_at, known_ids, max_pages=20, **filters):
    """Listings discovered at or after `last_seen_at` that are not in `known_ids`."""
    fresh, cursor = [], None
    for _ in range(max_pages):
        params = {"sort": "latest", "limit": 250, **filters}
        if cursor:
            params["cursor"] = cursor
        response = session.get(URL, params=params, timeout=30)
        response.raise_for_status()
        page = response.json()

        for row in page["data"]:
            if last_seen_at and row["discovered_at"] < last_seen_at:
                return fresh              # older than anything new: done
            if row["id"] not in known_ids:
                fresh.append(row)

        if not page["has_more"]:
            return fresh
        cursor = page["next_cursor"]
        time.sleep(0.6)
    return fresh


fresh = new_listings("2026-09-15T00:00:00.000Z", known_ids=set(), tier="open", spam="low")
print(len(fresh), "new listings")
if fresh:
    print("next last_seen_at:", max(row["discovered_at"] for row in fresh))

Timestamps are ISO 8601 in UTC with the same format on every row, so comparing the strings compares the instants. Store the newest discovered_at you saw and the ids at that timestamp, and pass both on the next run.

Keep sort=latest and your filters the same on every page of a run. A cursor belongs to the ordering and the query it came from.

Narrow what you poll for

Everything in Filters combines with sort=latest. Useful ones for this job:

  • tier=open — only names you may republish, which arrive with their names on every plan.
  • category, tld — the niche you are watching.
  • rsMin, rd — a quality floor. New listings are often the sparsest: the five newest open-tier listings on 23 September 2026 all lacked age, category and Agent Citability.
  • checkedDays — only rows whose availability was checked recently.

Before you act on a new listing

availability_checked_at is when Revised last confirmed the name was unregistered. New listings are not re-checked when you read them, and a newly dropped name is exactly the kind someone else is also watching. Confirm at a registrar before you act. See Availability is a stamp, not a check.

sort=latest or since?

sort=latestsince
AnswersWhat entered the directory?What changed, including what left?
PlansAllBusiness only
Ordered bydiscovered_at, newest firstListing id
Returns tombstonesNoYes

They cannot be combined. To keep a local copy correct, use since. To watch for new names, use sort=latest.

Over MCP

search_domains takes sort: "newest" for the same ordering, capped at 50 rows with no paging:

Show me the 20 newest open-tier SaaS listings with a low spam band.

Type to search…

↑↓ navigate openesc close