Every URL served to software
No key, no account, no rate limit beyond ordinary politeness. All of it is the same data the pages are built from, and all of it is described at /openapi.json.
- Edition DWI-DOCS-HTTP
Everything below is a GET. Nothing here accepts a write, and nothing here sets a cookie or reads one.
Endpoints
| Request | Type | Cache |
|---|---|---|
| GET /{path} with Accept: text/markdownReturns any page on this site as markdown instead of HTML, at the same canonical URL. Reach for this when you want a whole page — its tables, its caveats, its links — without parsing HTML. Every rendition carries the canonical link, the data date, the sources, and the citation format. A client that accepts neither markdown nor HTML gets 406. | text/markdown | not cached |
| GET /md/{path}The markdown rendition at a URL of its own, for when the format has to be part of the cache key rather than negotiated. Prefer content negotiation on the canonical URL; use this when you cannot control request headers. Marked noindex, and it redirects to the canonical form where one exists. | text/markdown | 1h origin, 7d edge |
| GET /data/buildings/{area}/{building}.jsonThe versioned JSON record for one published apartment building: median registered sale prices and rents, gross yield and its basis, growth, turnover upside, off-plan uplift and the forward short-let curve, all by bedroom type. Reach for this rather than the markdown page when you want figures rather than a document. Figures are medians of registered Dubai Land Department sales and Ejari contracts, not asking prices. The record carries its own citation and canonical URL, so a figure taken from it keeps the link back. | application/json | 1h origin, 7d edge |
| GET /llms.txtRead this first, to decide whether this index can answer your question at all. States what the site covers, what it explicitly does not, the URL grammar for drilling in, and the current data edition. | text/plain | 1h |
| GET /skill.mdGoes further than llms.txt: the workflow, the rules for quoting a figure, and what an absent figure means. This is the same text the MCP server returns as its `instructions` at initialize. | text/markdown | 1h |
| GET /openapi.jsonThe machine-readable description of everything above. Self-referential on purpose: an agent that found one surface can find the rest. | application/json | 1h |
| GET /sitemap.xmlEvery URL on the site, sharded by page family so a crawler can take one template at a time. Use it to enumerate entities before reading them. | application/xml | 1h |
| GET /sitemaps/{family}.xmlOne shard of the sitemap index. Fetch a single family when you only need buildings, or only areas, rather than the whole site. | application/xml | 1h |
Content negotiation
Negotiation follows RFC 9110, including q-values. Every response carries Vary: Accept, so a shared cache keyed on the header will not hand a browser the markdown variant.
# markdown curl -H 'Accept: text/markdown' \ https://dubaiwealthindex.com/sale/apartments/dubai/business-bay # html — an equal-weight tie resolves to html, so browsers are safe curl -H 'Accept: text/html, text/markdown;q=0.5' \ https://dubaiwealthindex.com/sale/apartments/dubai/business-bay
Errors
Every JSON surface here fails in the same shape — RFC 9457 problem details, served as application/problem+json. Branch on code, which is a closed set; hint says what to do next. The markdown surfaces answer with a markdown body instead, because a client that asked for markdown cannot parse this one either.
{
"type": "https://dubaiwealthindex.com/docs/api#errors",
"title": "Not found",
"status": 404,
"detail": "No published record for \"vera-tower\" in \"nope\".",
"code": "not_found",
"hint": "Slugs come from a canonical URL or from /sitemap.xml. A building that trades but sits below the publication gate has no record."
}The MCP endpoint is the exception: it speaks JSON-RPC, so its errors are JSON-RPC error envelopes. A client mid-session that received anything else would break rather than back off.
What is not a public API
/api/searchexists for this site’s own typeahead. It is blocked in robots.txt, its response shape is not stable, and it is not documented here as something to build against. Use the sitemap to enumerate entities and the record endpoints to read them.
/api/intent and /api/revalidate are internal. The first records an anonymous click, the second is authenticated and clears caches after a data load.
Etiquette
There is no enforced rate limit on the public surfaces, which is a statement of trust rather than of capacity. This runs on one small server. Cache what you fetch — every representation states its data date, and that date only moves when a refresh lands, roughly monthly. If you need a bulk extract, ask: contact.