API reference
Everything on this site goes through this API: search, checkout, owner actions and the marketplace. No key, CORS open. Wallet actions are signed messages (free) or transactions you sign and send yourself. SOL amounts are decimal strings ("1.5"), never floats.
Base URL https://mktp.domains/api/v1
Search & prices
GET/search?q=nova
Availability and price of a name across extensions. q can be a name or a full domain. page=1, 2… for more extensions (24 per page). Includes marketplace listings that match.
/api/v1/searchcurl "https://mktp.domains/api/v1/search?q=nova"
{
"label": "nova",
"exact": null,
"results": [
{ "domain": "nova.io", "status": "available", "usd": 89.99, "regularUsd": null, "renewUsd": 89.99 },
{ "domain": "nova.com", "status": "taken", "usd": null }
],
"more": true,
"solUsd": 172.4,
"market": [ { "domain": "nova.si", "price": "2.5", … } ]
}status is available, taken, premium (not sold here) or unsupported. Prices are per year in USD.
GET/check?domains=nova.io,nova.dev
The registry's own answer for up to 10 domains (slower than /search, which pre-checks through DNS). Use it right before checkout; premium domains come back as premium.
GET/tlds
Every extension sold here with its first-year and renewal price; featured ones first, sales flagged with regularUsd and promoEndsAt.
Register & renew
1.Open a checkout
POST /orders { "buyer": "<wallet>", "target": "<wallet the domains open>", "items": [ { "domain": "nova.io" }, { "domain": "old.xyz", "kind": "renew" } ] } → { "order": { "id": "…", "status": "awaiting", "sol": 0.52, … }, "transaction": "<base64 v0>" }
Up to 10 domains. Every new domain is re-checked live; the SOL amount is locked for 10 minutes.
2.Sign, send, confirm
POST /orders/{id}/confirm { "signature": "<transaction signature>" } GET /orders/{id} → status: paid → done (or partial / refunded)
Each item becomes done or failed. A domain that cannot be registered is refunded automatically, to the paying wallet.
Manage a domain
Domains bought here open a wallet on Solscan, or a link of your choice. The owner changes this with a signed message.
GET/domains/{domain}
Owner, expiry, where it opens, listing and sales of one domain.
GET/wallets/{address}
Domains a wallet owns (with listing state and settings) and its recent orders.
1.Get the message to sign
GET /message?action=target&domain=nova.io&value=<wallet>&wallet=<owner> GET /message?action=link&domain=nova.io&value=https://nova.app&wallet=<owner> GET /message?action=transfer&domain=nova.io&value=<new owner>&wallet=<owner> → { "message": "Point nova.io to … on mktp.domains\n…", "fields": { … }, "post": "/api/v1/domains/nova.io" }
2.Sign it and post it
POST /domains/{domain} { ...fields, "signature": "<base58 of signMessage(utf8(message))>" }
Marketplace
GET/listings
Live listings. q, tld, sort (new, price_asc, price_desc, expiry, name), min and max in SOL, seller, limit (max 200), offset.
/api/v1/listings{ "total": 42, "listings": [ { "domain": "nova.si", "seller": "…", "price": "1.5", "fee": "0.075", "total": "1.575", "expiresAt": "…", "pending": false } ] }price goes to the seller, fee is paid on top by the buyer, total is what the buyer pays. pending: someone is paying right now.
GET/sales
Completed sales, newest first. domain, limit (max 100).
GET/stats
Floor, number listed, volume (all time and 24 h), number of sales, tokens burned.
/api/v1/stats1.List, reprice or cancel (owner)
GET /message?action=list&domain=nova.si&price=1.5&wallet=<owner> (or action=cancel) POST /listings { ...fields, "signature": "<base58>" }
2.Buy
POST /purchases { "domain": "nova.si", "buyer": "<wallet>" } → { "purchase": { "id": "…" }, "transaction": "<base64 v0>" } (held {config.holdMinutes} min for this buyer) POST /purchases/{id}/confirm { "signature": "…" } → status "done": the domain is the buyer's
Errors & limits
Errors come back as { "error": "…" } with a meaningful status: 400 bad input, 401 bad signature, 403 not the owner, 404 not found, 409 conflict (taken, being bought, changed meanwhile), 429 too many requests, 503 checkout paused. Reads are cached for a few seconds.