Revised

Reveal a masked domain name, then hold it

Turn a masked listing into a registrable name, reserve it inside the directory, and handle every refusal the two calls can return.

Two calls act on a listing. POST /api/v1/domains/{id}/reveal turns a masked domain into a real name. POST /api/v1/domains/{id}/hold reserves the listing inside Revised while you make up your mind. They run in that order — a hold is refused until the same account has revealed the same listing.

Reveal

bash
curl -s -X POST https://getrevised.com/api/v1/domains/00aLaXEG/reveal \
  -H "Authorization: Bearer $REVISED_API_KEY"

It returns the listing in the same shape GET /api/v1/domains/{id} does, plus revealed_at, credits_charged and credits_remaining. The name below is a fabricated illustration — regular names are never published, here or anywhere else.

Example
json
{
  "id": "00aLaXEG",
  "status": "active",
  "domain": "greenvalleyfarms.com",
  "tier": "regular",
  "name_disclosed": true,
  "hold_state": "none",
  "revealed_at": "2026-09-22T03:15:02.117Z",
  "availability_checked_at": "2026-09-21T18:40:11.002Z",
  "credits_charged": 1,
  "credits_remaining": 29
}

What it costs

Where a ceiling applies, reveals are counted in credits. A regular reveal costs 1 credit and a featured reveal costs reveals.featured_credits (1 on Starter and Business); both are refused on Free, which has no reveals, and free of charge on Starter and Business, which have no ceiling. reveals.featured_credits on GET /api/v1/me gives the rate for your plan. credits_charged on the response says what this call actually spent, and credits_remaining what is left (null with no ceiling).

When it is free

These still write a ledger entry, so the reveal is recorded either way. That matters, because that record is what a hold checks:

  • The listing is on the open tier. Its name is published on the Revised site anyway.
  • Your plan has no reveal ceiling.
  • You already revealed it. See below.

Refund if just registered

Every first reveal re-checks availability, on every plan. If the re-check finds the name was registered since our last check, the reveal costs 0 credits. The response carries credits_charged: 0, refunded: true and a note:

json
{
  "credits_charged": 0,
  "refunded": true,
  "note": "Registered since our last check — your credit was refunded."
}

It is idempotent

A repeat call returns the original revealed_at, costs nothing, and is the safe way to re-read a name you have already revealed. You do not need to cache names defensively to avoid spending twice.

python
def reveal(session, listing_id):
    response = session.post(
        f"https://getrevised.com/api/v1/domains/{listing_id}/reveal", timeout=30
    )
    if response.status_code >= 400:
        error = response.json()["error"]
        raise RuntimeError(f"{response.status_code} {error.get('reveal_code')}: {error['message']}")
    return response.json()

Reveal refusals

Branch on error.reveal_code, not on the HTTP status — several codes share a status.

reveal_codeStatusWhat to do
QUOTA_EXHAUSTED402Not enough credits for this reveal. The error carries credits_needed, credits_remaining and resets_at. A featured reveal can be refused with credits left; an ordinary listing may still fit. Otherwise stop until resets_at, or upgrade.
FEATURED_REQUIRES_PRO402The Free plan cannot reveal a featured listing. Any paid plan can. Skip the row or upgrade.
HELD_BY_OTHER403Another account holds it. The error carries expires_at — never who holds it. Retry after that, or move on.
NOT_FOUND404The listing has left the directory. Drop it from your working set.
REVEAL_FAILED500Transient. Retry once with backoff, then treat as a skip.
SIGN_IN_REQUIRED401The key did not resolve to an account.

A QUOTA_EXHAUSTED response is worth handling properly rather than retrying:

python
import requests

try:
    row = reveal(session, listing_id)
except RuntimeError as exc:
    if "QUOTA_EXHAUSTED" in str(exc):
        me = session.get("https://getrevised.com/api/v1/me", timeout=30).json()
        print(me["reveals"]["remaining"], "credits left until", me["reveals"]["resets_at"])
    raise

Hold

A hold takes the listing off the shelf for every other account for a plan-dependent window, and masks the name for them while it runs.

bash
curl -s -X POST https://getrevised.com/api/v1/domains/00aLaXEG/hold \
  -H "Authorization: Bearer $REVISED_API_KEY"
Example
json
{
  "hold": {
    "id": "3f8c2a1e-7b4d-4e9a-9c6f-2d1b5e8a7c30",
    "listing_id": "00aLaXEG",
    "held_at": "2026-09-22T03:16:40.000Z",
    "expires_at": "2026-09-24T03:16:40.000Z",
    "can_extend": true,
    "extend_hours": 24
  },
  "holds": { "plan": "starter", "active": 1, "limit": 5, "hold_hours": 48 }
}

Taking a hold you already have is not a second hold — the existing one comes back unchanged.

The holds block reports this account’s quota: how many holds are running, the plan’s ceiling, and how long a new hold runs for. The example is a Starter account — five holds of 48 hours, each extendable once by 24. Business allows 20 holds of 168 hours, and Free allows none; see Plans and limits. Read the numbers from the response rather than hard-coding them.

Holds are account-scoped, not key-scoped. Every key on the account sees, extends and can end the same holds. Separate keys for separate systems separate the rate-limit bookkeeping, not the holds.

Hold refusals

Branch on error.hold_code. Three of these are completely different next actions and they are easy to conflate:

hold_codeWhat happenedWhat to do
REVEAL_REQUIREDThis account has not revealed this listingCall reveal first, then retry the hold.
HELD_BY_OTHERSomebody else holds itThe error carries expires_at. The listing is free the moment their window closes.
HOLD_COOLDOWNYour own hold on this listing ended within the last 30 daysThe error carries available_at. Another account’s ended hold never blocks you — only yours does.
HOLD_CAP_REACHEDYou are at the plan’s ceilingThe error carries limit. End a hold you no longer need.
HOLDS_REQUIRE_PROThe plan does not include holdsUpgrade, or work without them.
ALREADY_EXTENDEDThe one permitted extension has been takenNothing. Let it run out or release it.
HOLD_NOT_FOUND, HOLD_OVERThe hold id is unknown, or has already endedRe-read GET /api/v1/holds.
HOLD_FAILEDAn unexpected server-side failure (500)Retry once with backoff. Taking a hold you already have is safe to repeat.
NOT_FOUNDThe listing has left the directoryDrop it.

Extend, once

bash
curl -s -X POST https://getrevised.com/api/v1/holds/3f8c2a1e-7b4d-4e9a-9c6f-2d1b5e8a7c30/extend \
  -H "Authorization: Bearer $REVISED_API_KEY"

The window extends from where it was going to end, not from now, so extending early loses you nothing. A second attempt is refused with ALREADY_EXTENDED.

End a hold

DELETE /api/v1/holds/{id} takes an outcome, defaulting to released:

bash
curl -s -X DELETE https://getrevised.com/api/v1/holds/3f8c2a1e-7b4d-4e9a-9c6f-2d1b5e8a7c30 \
  -H "Authorization: Bearer $REVISED_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "outcome": "registered" }'
Example
json
{
  "ended_at": "2026-09-22T09:02:11.000Z",
  "outcome": "registered",
  "registration": "taken",
  "holds": { "plan": "starter", "active": 0, "limit": 5, "hold_hours": 48 }
}
  • released gives the listing straight back to everyone else.
  • registered records that you registered the name yourself. That triggers an availability re-check and retires the listing if the name now resolves. The response’s registration field reports what the re-check found: taken means the name now resolves; unknown means no answer, which is not the same as available.
  • expired is not accepted. That outcome belongs to the clock.

Either way the listing is available to other accounts immediately, and you cannot hold that same listing again for 30 days.

Review your holds

bash
curl -s https://getrevised.com/api/v1/holds \
  -H "Authorization: Bearer $REVISED_API_KEY" | jq
Example
json
{
  "active": [
    {
      "id": "3f8c2a1e-7b4d-4e9a-9c6f-2d1b5e8a7c30",
      "listing_id": "00aLaXEG",
      "domain": "greenvalleyfarms.com",
      "held_at": "2026-09-22T03:16:40.000Z",
      "expires_at": "2026-09-24T03:16:40.000Z",
      "can_extend": true,
      "extend_hours": 24
    }
  ],
  "ended": [
    {
      "id": "9a41d7c2-0e5b-4f3a-8d2c-6b7e1f0a4c95",
      "listing_id": "X00w46xl",
      "ended_at": "2026-09-14T22:05:00.000Z",
      "outcome": "expired",
      "expires_at": "2026-09-14T22:05:00.000Z",
      "held_at": "2026-09-12T22:05:00.000Z",
      "can_extend": false
    }
  ],
  "holds": { "plan": "starter", "active": 1, "limit": 5, "hold_hours": 48 }
}

Active holds carry domain, because a hold requires a reveal of the same listing by the same account. Ended holds carry their outcome — expired, released or registered.

The full flow

  1. Filter and rank

    Page GET /api/v1/domains. Free, and it never charges for the rows it matched. See Find domains.

  2. Reveal the shortlist, not the page

    One reveal per listing you are seriously considering. Repeat calls are free, so you never need to cache the name to protect your quota.

  3. Hold what you want to research

    Refused with REVEAL_REQUIRED until step 2 has run for that listing on this account.

  4. Confirm availability at a registrar

    availability_checked_at is a stamp, not a live check, and a hold does not reserve the name outside Revised.

  5. End the hold with the truth

    registered if you took the name, released if you did not. The 30-day cooldown on your own re-hold starts either way.

Type to search…

↑↓ navigate↵ openesc close