Revised

Reveal a 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 write calls exist on this API. 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_KEY"

It returns the listing in the same shape GET /api/v1/domains/{id} does, plus revealed_at. 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"
}

When it is free

Both of these still write a ledger entry, so the reveal is recorded either way — which 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.

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 bought. You do not need to cache names defensively to avoid double-charging.

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_EXHAUSTED402The month’s allowance is gone. The error carries resets_at. Stop revealing until then, or upgrade.
FEATURED_REQUIRES_PRO402A free plan cannot reveal a featured listing. 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_FAILEDTransient. 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("out of reveals 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_KEY"
Example
json
{
  "hold": {
    "id": "hold_7f3a91c2",
    "listing_id": "00aLaXEG",
    "held_at": "2026-09-22T03:16:40.000Z",
    "expires_at": "2026-09-24T03:16:40.000Z",
    "can_extend": true,
    "extend_hours": 48
  },
  "holds": { "plan": "pro", "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. Those numbers are plan-dependent — read them from the response rather than assuming the ones above.

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.
NOT_FOUNDThe listing has left the directoryDrop it.

Extend, once

bash
curl -s -X POST https://getrevised.com/api/v1/holds/hold_7f3a91c2/extend \
  -H "Authorization: Bearer $REVISED_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/hold_7f3a91c2 \
  -H "Authorization: Bearer $REVISED_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": "pro", "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_KEY" | jq
Example
json
{
  "active": [
    {
      "id": "hold_7f3a91c2",
      "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": 48
    }
  ],
  "ended": [
    {
      "id": "hold_4b18de07",
      "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": "pro", "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 outcomeexpired, 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