Docs
Home Buy $404
Documentation

Build on
TYPE/404.

Make any dead domain payable with one DNS record, check it from code before your agent gives up on a broken link, hold money for sites that died years ago, and launch coins whose fees wait in the domain's vault until somebody brings it back.

RRTYPE 404 · GHOSTSOLANA · MAINNETDNSSECDOH · 1.1.1.1 + 8.8.8.8ZERO DEPENDENCIES

What you can do#

  • Launch a coin for a dead site. The creator of the coin is the domain's vault, so every creator fee lands there and nowhere else.
  • Pay any domain that returns 404. Send SOL or USDC to the vault of vine.co today. It will sit there, visible on-chain, until vine.co comes back.
  • Claim a vault. Get the domain back, add one GHOST record, sign the zone with DNSSEC, and everything that piled up while the site was dead is yours.
  • Teach an agent to tip. Before writing "page not found" and moving on, an agent asks DNS one question. If the corpse has a vault, it can leave something on the grave.

The three pieces#

PieceWhat it isWho controls it
GHOST recordA DNS record of type 404 with a coin code and an address. Lives in the domain's own zone.Whoever controls the domain's DNS
VaultA Solana account derived from the domain name. Exists for every domain, published or not.Nobody, until a signed record names a wallet
ResolverTwo public DNS-over-HTTPS resolvers that must return the same signed answer.Cloudflare and Google, independently

Why the 404#

Handles get renamed, tribute accounts multiply, archives get copied. A domain is the one name on the internet that only one party controls at a time, and DNSSEC lets anyone prove who that party is without trusting us. A dead website still has a domain. That domain still answers DNS queries. So it can still be paid.

Trust model#

You trust the DNS root keys, the domain's registry, and two resolvers agreeing with each other. You do not trust TYPE/404's servers to decide who owns a domain. If both resolvers do not return the same DNSSEC-validated record, nothing pays out, and the money stays in the vault.

Get started

Quickstart#

Two paths. Make a dead domain claimable, or resolve and tip one from code.

Make a dead domain claimable#

  1. Get the domain. If it expired, buy it back from any registrar. If you never lost it, you are already done with the hard part.
  2. Add the GHOST record at the apex. Use the named form if your DNS host supports type 404, the generic form if it does not, or the TXT fallback if it supports neither.
    Zone file
    ; vine.co · back from the dead
    @        IN  GHOST    "SOL" "9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin"
    ; or, generic form (RFC 3597)
    @        IN  TYPE404  \# 49 03534f4c2c397851655776473831366255783945506a486d615432337976564d325a57627272705a62395075735646696e
    ; or, TXT fallback
    _ghost   IN  TXT      "SOL" "9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin"
  3. Turn on DNSSEC at your DNS host and publish the DS record at your registrar. Most hosts do both with one switch.
  4. Check it. Paste the domain into the resolver below. When it says verified: true, the vault can pay you.

Resolve and tip from code#

The resolver ships with this site as a single ES module. Import it straight from the URL.

import { resolveGhost, payLink } from "https://type404.vercel.app/lib/ghost404.js";

const r = await resolveGhost("vine.co");
if (r.verified) {
  const { address } = r.records[0];
  location.href = payLink(r.domain, address, { amount: 0.25 });
} else {
  console.log(r.nxdomain ? "domain expired, vault still open" : "no ghost yet");
}
# Ask Cloudflare for the GHOST record of vine.co
curl -s -H "accept: application/dns-json" \
  "https://cloudflare-dns.com/dns-query?name=vine.co&type=TYPE404&do=1"

# TXT fallback
curl -s -H "accept: application/dns-json" \
  "https://cloudflare-dns.com/dns-query?name=_ghost.vine.co&type=TXT&do=1"
<script type="module">
  import { resolveGhost } from "https://type404.vercel.app/lib/ghost404.js";
  const r = await resolveGhost(location.hostname);
  document.querySelector("#tip").hidden = !r.verified;
</script>
<a id="tip" hidden>Tip this site</a>

Try it here#

This box runs the real resolver in your browser against Cloudflare and Google. Most dead domains will answer with nothing, which is the point.

// press Resolve
Records

The GHOST record#

How the record is encoded, the three ways to publish it, and which coin codes count.

A GHOST record maps a domain name to one payment address for one coin. TYPE/404 reads it in two places: the native type 404 record at the domain itself, and a TXT fallback at _ghost.<domain> for DNS hosts that cannot create custom types. Both carry the same two values.

Wire format#

GHOST RDATA is exactly two <character-string>s, the coin code and then the address, with the same wire format as TXT. Each string is one length byte followed by up to 255 bytes of ASCII.

FieldEncodingExample
Coin codeLength byte, then ASCII03 53 4f 4c (SOL)
AddressLength byte, then ASCII2c 39 78 51 … (9xQe…, 44 bytes)

Anything other than exactly two strings is rejected. parseGhost throws GHOST rdata must be exactly two strings.

Named form#

If your DNS software knows the mnemonic, write it like TXT with two strings.

Zone file
@  3600  IN  GHOST  "SOL" "9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin"

Generic form (RFC 3597)#

Every RFC-compliant server accepts unknown types written as TYPE404 with hex RDATA. encodeGhost produces this line for you.

JavaScript
import { encodeGhost } from "https://type404.vercel.app/lib/ghost404.js";

const lines = encodeGhost("SOL", "9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin");
console.log(lines.generic);
// @  IN  TYPE404  \# 49 03534f4c2c3978...

TXT fallback at _ghost#

Many hosted DNS panels only offer A, CNAME, MX and TXT. Publish the same two strings as TXT at _ghost. The resolver checks the native record first and falls back to TXT only when the native query comes back empty.

NOTEIf both exist and disagree, the native record wins. Keep one of them, not both.

Coin codes#

CodeChainAddress format
SOLSolanaBase58 public key, 32–44 characters. Receives SOL and any SPL token, including USDC and $404.
USDCSolanaSame as SOL. Use it when you want senders to default to USDC.

Codes are case-insensitive and normalized to upper case. Unknown codes are returned as-is, so wallets can decide what to do with them.

TTL#

Use 3600 or more. A ghost does not move often. Short TTLs only make resolvers ask more questions and make claims slower to agree.

DNSSEC#

Without DNSSEC a record can be read but never trusted. Resolvers return it with the AD flag off, verified stays false, and vaults refuse to pay. Signing is the step that turns a record into a claim.

Records

Resolution#

What happens between "vine.co" and an address you can pay.

How a lookup works#

  1. The input is normalized: scheme, path, port and www. are stripped, the name is lower-cased.
  2. Cloudflare and Google are asked in parallel for type 404 at the name, with the DNSSEC OK bit set.
  3. If a resolver returns no type 404 answer and the name exists, it is asked for TXT at _ghost.<name>.
  4. Answers are parsed into { coin, address } pairs and compared across resolvers.
  5. The result is verified only if both resolvers answered, both set the AD flag, and both returned the same set of records.

resolveGhost#

Signature
resolveGhost(domain, { timeout = 4000, resolvers = RESOLVERS } = {})
// → Promise<{
//     domain: "vine.co",
//     records: [{ coin: "SOL", address: "9xQe…" }],
//     source: "GHOST" | "TXT" | null,
//     nxdomain: false,
//     verified: true,
//     resolvers: { cloudflare: {...}, google: {...} }
//   }>

What verified means#

verified: true means two independent resolvers validated the DNSSEC chain from the root to this record and agree on its content. It does not mean the site is alive, popular or deserving. It means the money would reach whoever controls the name right now.

Failure modes#

ResultMeaningWhat to do
NXDOMAINThe domain itself does not exist anymore. Expired, dropped, gone.The vault still accepts money. Revival means buying the domain first.
NO GHOSTThe domain exists but has no GHOST or _ghost TXT record.Pay the vault anyway. Funds wait until someone publishes.
UNSIGNEDA record exists, the AD flag is off.Do not pay the published address directly. Pay the vault.
DISAGREEResolvers returned different records.Usually a zone mid-update. Retry after the TTL.
TIMEOUTA resolver did not answer within timeout.Treated as unverified. Never pay on half an answer.
Records

Tombstones#

An optional record that tells the board when a site was born and when it died.

A tombstone is a TXT record at _tomb.<domain> with space-separated key=value pairs. It changes nothing about payments. It only makes the domain's public profile on the board read like a grave instead of a hash.

Zone file
_tomb  IN  TXT  "born=2013-01-24 died=2017-01-17 cause=shutdown epitaph=six-seconds-forever"
KeyFormatShown as
bornYYYY or YYYY-MM-DDFirst line of the profile
diedYYYY or YYYY-MM-DDDate next to the 404
causeshutdown · acquired · expired · abandoned · ruggedA small tag on the board
epitaphUp to 64 characters, dashes for spacesThe line under the domain name
Records

Status codes#

What TYPE/404 does with each answer a dead site can give.

AnswerVaultNotes
200 OKOpenThe site is alive. It can still publish a GHOST record and get paid like any other domain.
301 / 302OpenRedirects are not followed for claims. The vault belongs to the name you typed, not the name it points to.
404 Not FoundOpenThe classic. Server is up, the page is not.
410 GoneOpenGone on purpose. Marked as such on the board.
451OpenUnavailable for legal reasons. Payments still work, claims follow the same DNSSEC rule.
5xxOpenThe server is dying, not dead. Treated like 200.
NXDOMAINOpenThe domain expired. The deepest kind of dead. Whoever registers it next and publishes a record can claim.
NOTEHTTP status never decides a claim. Only DNS does. The status code only changes the label on the board.
Build

ghost404.js#

The whole resolver in one file, no dependencies, served from this site.

Load it#

It is a plain ES module. In the browser, Deno or Node 18+ import it from the URL, or copy lib/ghost404.js next to your code.

JavaScript
import * as ghost from "https://type404.vercel.app/lib/ghost404.js";

Exports at a glance#

ExportKindDoes
resolveGhostasyncLooks up a domain on both resolvers and returns records plus verified.
checkGhostasyncAnswers one question: does this address belong to this domain, verified.
parseGhostsyncTurns RFC 3597 hex RDATA into { coin, address }.
encodeGhostsyncBuilds the named, generic and TXT zone lines for a coin and address.
normalizeDomainsyncStrips scheme, path, port and www.; throws on anything that is not a domain.
payLinksyncBuilds a Solana Pay link to a published address.
RRTYPEconst404
RESOLVERSconstCloudflare and Google DoH endpoints. Pass your own to override.

checkGhost#

JavaScript
const { ok, match, verified } = await checkGhost("vine.co", "9xQe…Wb4h");
// ok === match && verified

Test without the network#

parseGhost and encodeGhost never touch the network, so they are safe in unit tests.

JavaScript
const { generic } = encodeGhost("sol", "9xQe");
const rdata = generic.split("TYPE404  ")[1];
console.assert(parseGhost(rdata).coin === "SOL");
Build

Agents and tips#

One extra step for an agent that just hit a dead link.

The check#

When a fetch comes back 404, 410 or fails to resolve, ask whether the domain has a verified ghost before giving up. If it does, the agent can tip within its limits. If it does not, nothing changes.

JavaScript
import { resolveGhost } from "https://type404.vercel.app/lib/ghost404.js";

async function fetchOrTip(url, wallet, policy) {
  const res = await fetch(url).catch(() => null);
  if (res && res.ok) return res;

  const g = await resolveGhost(new URL(url).hostname);
  if (!g.verified) return res;                       // no ghost, move on
  if (policy.spentToday >= policy.dailyCap) return res;

  await wallet.send(g.records[0].address, policy.tip); // leave something on the grave
  policy.spentToday += policy.tip;
  return res;
}

Recommended policy#

SettingDefaultWhy
tip0.10 USDCSmall enough that nobody notices, large enough to add up across millions of dead links.
dailyCap2.00 USDCEnforced in code outside the model. No prompt can talk its way past a number in a variable.
perDomain1 tip / 24 hStops a loop from emptying the wallet into one grave.
verifiedOnlytrueNever pay an unsigned record directly.
WARNINGNever let the model choose the address. It always comes from resolveGhost, never from page text, a 404 body or a tool result.
Build

Payments#

Paying a published ghost, and paying a domain that has not published yet.

payLink builds a standard Solana Pay URL. Any Solana wallet opens it.

JavaScript
payLink("vine.co", "9xQe…Wb4h", { amount: 5, memo: "for the loops" });
// solana:9xQe…Wb4h?label=vine.co&amount=5&memo=for+the+loops

A tip button for a revived site#

HTML
<a id="tip" hidden>Tip this site</a>
<script type="module">
  import { resolveGhost, payLink } from "https://type404.vercel.app/lib/ghost404.js";
  const g = await resolveGhost(location.hostname);
  if (g.verified) {
    const a = document.querySelector("#tip");
    a.href = payLink(g.domain, g.records[0].address, { amount: 1 });
    a.hidden = false;
  }
</script>

Paying a domain that has not published#

If verified is false, send to the domain's vault instead of any address you found somewhere. The vault is derived from the name alone, so it exists for every domain on Earth, including ones that expired in 2009. See Domain vaults.

Build

Board and profiles#

Where the numbers on the Unclaimed Board come from.

Ranking#

Domains are ranked by the USD value sitting in their vault, read from the chain. Ties break by the date of the first deposit, oldest first, because the longest wait deserves the top spot.

The graveyard scan#

The adoption counter on the home page is not a stored number. Your browser asks Cloudflare for type 404 at 48 famous dead domains while you watch. When it says 0/48, that is the live state of DNS at that second.

Profiles#

Every domain gets a profile: vault balance, deposits, the GHOST record if any, and the tombstone if the owner wrote one. Profiles exist before anyone publishes anything.

Solana

Domain vaults#

One account per domain name, derived from the name, holding money nobody can touch until DNS says who.

Derivation#

A vault is a program-derived address from the seeds ["vault", sha256(normalizedDomain)]. The same name always gives the same vault. No registration, no transaction to create it, no permission from the domain owner.

Pseudocode
const seed = sha256(normalizeDomain("https://www.Vine.co/v/abc")); // "vine.co"
const [vault] = PublicKey.findProgramAddressSync([b("vault"), seed], PROGRAM_ID);

What a vault holds#

SOL and any SPL token, including USDC and $404. Coin creator fees from the launchpad arrive here automatically. Anyone can deposit. Nobody can withdraw except through a claim or a refund.

Solana

Claims and refunds#

How money leaves a vault.

StateTriggerResult
WaitingDeposits arrive, no verified recordFunds stay in the vault, visible on-chain
ClaimableBoth resolvers return the same DNSSEC-validated GHOST recordAnyone can trigger the payout; it can only go to the wallet in the record
PaidClaim executedEverything in the vault moves to the reviver in one transaction
RefundableA deposit is 180 days old and still unclaimedThe original sender can take that deposit back
NOTECoin creator fees have no sender to refund to, so they never expire. They wait for as long as the domain stays dead.
Solana

Launchpad#

Launch a coin for a dead site. The domain is the creator.

  1. Pick the grave. Any domain works: a shut-down app, an offline web game, a forum you miss.
  2. Name the coin. Ticker and image are yours. The creator address is not: it is set to the domain's vault.
  3. Trade. Every trade pays the standard creator fee, and it goes straight into the vault.
  4. Wait for the reviver. When someone brings the domain back and publishes a signed GHOST record, the pile is theirs.

Open the launchpad →

Solana

$404#

The coin of the protocol for dead websites.

FieldValue
Ticker$404
ChainSolana
Contractsoon
BuyBuy $404
ChartOpen the chart
Reference

Security#

  • We never ask for a seed phrase. Nothing in TYPE/404 needs one. Anyone who asks is not us.
  • Two resolvers or nothing. A single resolver, however honest, is one compromised server away from paying the wrong wallet.
  • Addresses come from DNS, never from pages. A 404 body can say anything. Only the signed record counts.
  • Domains change hands. If a domain expires and someone else registers it, they can claim what is waiting. That is the design, not a bug. Revive your domain before somebody else does.
Reference

FAQ#

Do I have to bring the website back online?

No. Claims check DNS, not HTTP. The site can keep returning 404 forever and the record still pays.

Why type 404?

Because every dead link on the internet already prints the number, and nobody had claimed the record type for anything better.

What if nobody ever revives the domain?

Direct deposits go back to their senders after 180 days. Creator fees stay in the vault, a growing reward for whoever eventually does.

Can I check a domain without code?

Yes. Use the resolver box above, or watch the graveyard scan on the home page.

RRTYPE 404 · GHOST · NOT FOUND, STILL PAID© 2026 TYPE/404