List domains
Listings matching the filters, in ascending listing-id order, or newest `discovered_at` first with `sort=latest`. Page with `cursor` until `next_cursor` is null. Every plan may read this; a plan with a reveal ceiling receives `domain` on open-tier rows and on rows it has already revealed, and `null` with a `mask_hint` on the rest — this call never spends a reveal to fill one in. Poll with `since` for what has changed, on a plan that includes it: a `since` page mixes full listings with tombstones for rows that have left the directory, and every row carries `status`, so read that first.
/api/v1/domainsListings matching the filters, in ascending listing-id order, or newest `discovered_at` first with `sort=latest`. Page with `cursor` until `next_cursor` is null. Every plan may read this; a plan with a reveal ceiling receives `domain` on open-tier rows and on rows it has already revealed, and `null` with a `mask_hint` on the rest — this call never spends a reveal to fill one in. Poll with `since` for what has changed, on a plan that includes it: a `since` page mixes full listings with tombstones for rows that have left the directory, and every row carries `status`, so read that first.
Authorizations
AuthorizationstringheaderrequiredBearer authentication header of the form Bearer <token>, where <token> is your auth token.
Query parameters
cursorstringOpaque cursor from a previous response's `next_cursor`. Both orderings this endpoint offers are over columns that are written once and never rewritten, so a cursor never skips or repeats a row. A cursor BELONGS TO the ordering it came from — the default's is a listing id, `sort=latest`'s is a position in that order — so pass the same `sort` on every page of a run. TREAT IT AS OPAQUE AND DO NOT CONSTRUCT ONE: the value is checked for shape AND for a position this directory actually holds, so a cursor this endpoint did not issue is a 400 `invalid_request` — never an empty page, and never a silent resume from the middle of the feed.
limitintegerdefault: 50Rows per page. An integer out of range is CLAMPED, not rejected — above 250 you get 250, below 1 you get 1. A `limit` that is not a whole number is refused with 400 `invalid_request`, and that INCLUDES the empty string: `?limit=` is what `?limit=${n}` sends for an undefined n, and answering it with a page size of 1 would quietly make a full sync 250 times longer.
sincestring (date-time)BUSINESS PLAN ONLY — every other parameter and endpoint here answers every plan; this one is refused with `upgrade_required` (402) on Free and Pro, and paging with `cursor` reaches the same rows without it. ISO 8601 instant. Inclusive: rows whose `updated_at` is AT or after it, INCLUDING rows that have left the directory since — those come back as tombstones (`status: "delisted"`, no other fields). Use the `synced_at` from the FIRST page of your previous run: it is read before any row is, so a listing updated mid-run is picked up next time rather than skipped. Consecutive polls OVERLAP by design — `synced_at` trails server time by 120 seconds so that a row written just before your last poll cannot fall through the gap between being stamped and being committed. Expect to see rows again; every row is idempotent by `id` plus `updated_at`, so upsert on `id` and ignore one you already hold at that `updated_at`.
sort"latest"Ordering. Omitted: ascending listing id, the default. `latest`: newest `discovered_at` first, tie-broken by id. No other value is accepted. `latest` cannot be combined with `since` — that one is the incremental-sync feed and is ordered by id.
Available options: latest
ageMinintegerFilter, passed through to the directory query.
categorystringCategory code, e.g. `education` or `saas`. Comma-separate for several. The codes are the `category` values listings come back with; there is no closed list, so read one off a page of results rather than guessing. An unknown code is refused, not silently ignored.
checkedDaysintegerFilter, passed through to the directory query.
citabilityMinintegerFilter, passed through to the directory query.
featuredbooleanFilter, passed through to the directory query.
priceRangestringEstimated-value band, bucketed on the same figure the response reports as `estimated_value_cents` — filter by a band and the values you get back are inside it.
Available options: under-100, 100-249, 250-999, 1000-2499, 2500-plus
qstringFree-text search across the masked hint, tags, category and blurb. Deliberately NOT the real name: searching for a name you already have in mind will not find it, whatever your plan and whatever tier the listing is on. Use `GET /domains/{id}` when you know the id.
rdstringFilter, passed through to the directory query.
recommendedbooleanOnly listings that pass the recommended heuristic (categorised, at least one marquee linker, Revised Score floor).
rsMaxintegerFilter, passed through to the directory query.
rsMinintegerMinimum Revised Score (lower bound of the published range).
sourcestringFilter, passed through to the directory query.
spam"low" | "moderate"Filter. One of: low, moderate.
Available options: low, moderate
tier"open"Filter. One of: open.
Available options: open
tldstringExact TLD, without the dot — `com`, `com.au`.
Responses
A page of listings.
dataobject | object[]requiredhas_morebooleanrequirednext_cursoranyrequiredsynced_atstring (date-time)requiredWatermark for your NEXT run. Taken before this page was read and deliberately held 120 seconds behind server time, so polling with it re-delivers rows you already have rather than risking one that was mid-commit. Pass the first page's value as the next run's `since`.
curl --request GET \
--url "https://getrevised.com/api/v1/domains" \
--header "Authorization: Bearer YOUR_API_KEY"{
"data": [],
"has_more": true,
"next_cursor": {},
"synced_at": "2023-11-07T05:31:56Z"
}