One small, separately deployed Worker that serves shared, read-only data to every internal
tool — starting with the navigation menu each tool renders in its own UI.
Every response is read-only, non-sensitive, and identical for every caller.
There is no per-user data, no authentication, and no filtering — if something wouldn't be
fine to hand to anyone who can reach this URL, it does not belong in this service.
What protects it, how paths and versions are structured, and how to consume it well.
Access model
The only protection is which hostname is calling. A cross-origin request's Origin
must be on the allowlist below (echoed back in Access-Control-Allow-Origin) or it
gets 403; a same-origin request is checked against its own hostname instead.
This stops other sites from embedding this data in a browser. It does not stop
a direct request — an acceptable trade because nothing served here is sensitive.
utm.basworld.online
shell.basworld.online
localhost
127.0.0.1
Conventions
Every endpoint lives at /{endpoint}/v{major} — nav is simply the first.
Cached at the edge: Cache-Control: public, max-age=300, stale-while-revalidate=3600 by default.
A breaking response-shape change ships as a new major version, served alongside the old one. Additive changes (new optional field, new node type) stay on the current version.
Forward compatibility: skip node types you don't recognise, skip malformed nodes, and only treat a response as unavailable if nothing valid survives.
Recommended client behaviour
Fetch with a short timeout — don't let this service block your tool's own render.
Cache the last good response in localStorage and render that while re-fetching.
Keep a small local fallback for first-load-ever, with no cache and no network.
If nothing valid survives, fail quietly — don't show an error where a menu should be.
One level of nesting: a group's items are links only, never groups.
id values are a public contract — never rename or reuse one; retire it and add a new id instead.
Order is exactly as written in the response. Do not sort items client-side.
Links with target "_blank" must be rendered with rel="noopener noreferrer".
Forward compatibility: skip node types you don't recognise and skip malformed nodes; only treat the whole menu as unavailable if nothing valid survives.