documentation
The .fomo resolver API
Turn a .fomo domain into the Solana address behind it with a single HTTP request. Every read endpoint is public, CORS-open, cacheable, and requires no authentication.
quickstart
$ curl https://fomosns.wtf/api/resolve/alice.fomoA registered domain returns 200 with the resolution payload. An unregistered one returns 404. That is the whole integration surface for most applications.
Endpoints
GET /api/resolve/{domain}
Resolve a domain
Returns the address a domain points at, plus its owner. With or without the TLD: alice and alice.fomo are equivalent. Not rate limited; cache headers included. 404 when unregistered.
{
"name": "alice.fomo",
"tld": "fomo",
"owner": "7xKX…gAsU",
"target": "9WzD…AWWM",
"records": {},
"registeredAt": "2026-08-16T11:02:44.180Z"
}GET /api/check?name={name}
Check availability
Validates the name and reports availability. Always 200; read the available flag. A free result is a snapshot, not a hold — the database decides the winner at reservation time.
{
"available": true,
"normalized": "alice",
"tld": "fomo",
"priceSol": 0.1,
"priceLamports": 100000000
}GET /api/domains?limit=50&offset=0&q=
List the registry
Every confirmed domain, newest first. limit caps at 100; q is a case-insensitive substring filter.
{
"tld": "fomo",
"total": 128,
"limit": 50,
"offset": 0,
"domains": [ { "name": "alice", "fqdn": "alice.fomo", … } ]
}GET /api/wallet/{address}
Domains by wallet
Reverse lookup: everything a base58 address owns, newest first. Lists by owner, not target. Served no-store.
{
"owner": "7xKX…gAsU",
"tld": "fomo",
"count": 2,
"names": [ { "name": "alice", "fqdn": "alice.fomo", … } ]
}POST /api/register/reserve
Reserve a name
Body: { name, wallet }. Inserts a pending row with a fresh memo reference and a ten-minute expiry. A unique index decides races: the loser gets 409 NAME_UNAVAILABLE.
{
"reservationId": "…",
"memo": "fomo:reg:alice:1a2b3c4d",
"treasury": "F7R5…yRA2",
"lamports": 100000000,
"expiresAt": "…"
}POST /api/register/confirm
Confirm payment
Body: { reservationId, signature }. The server fetches the transaction itself and verifies: it landed with no error, the treasury's settled balance delta covers the price, a memo instruction exactly equals the reservation reference, and the fee payer is the reserving wallet. 425 TX_NOT_FOUND is retryable.
{
"ok": true,
"fqdn": "alice.fomo",
"owner": "7xKX…gAsU",
"signature": "4Nd1…",
"registeredAt": "…"
}Domain rules
- Character set — a-z, 0-9 and hyphens. The ASCII check runs on the raw input before lowercasing, so Unicode lookalikes are refused outright.
- Length — 3 to 63 characters, excluding the TLD.
- Hyphens — no leading, trailing, or consecutive hyphens.
- Reserved — admin, www, api, support, help, mail, root, system, official, and fomo itself.
Error codes
Non-2xx responses carry a stable error.code plus a human-readable message. Branch on the code.
| INVALID_NAME | 400 | The domain failed validation. |
| INVALID_WALLET | 400 | Not a valid base58 public key. |
| NOT_FOUND | 404 | The domain is not registered. |
| NAME_UNAVAILABLE | 409 | Taken, or held by a live reservation. |
| NO_RESERVATION | 404 | The reservation id does not exist. |
| RESERVATION_EXPIRED | 409 | The ten-minute window closed. |
| TX_NOT_FOUND | 425 | Not visible at confirmed commitment yet. Retryable. |
| TX_FAILED | 400 | The transaction landed but failed on-chain. |
| UNDERPAID | 400 | Treasury balance change below the required lamports. |
| MEMO_MISMATCH | 400 | Missing this reservation's memo reference. |
| PAYER_MISMATCH | 400 | A different wallet signed the payment. |
| SIGNATURE_ALREADY_USED | 409 | Transaction already credited to a domain. |
| NOT_CONFIGURED | 503 | Deployment is missing its credentials. |
| DB_ERROR | 500 | The registry database could not be reached. |
MVP notes: per-IP rate limits, record updates and transfers are not enforced or exposed yet. Registration is reserve → pay → confirm as documented above.