Docs · Guides
Legal scope integration
Rendering the list of domains the Liorith Legal Center is responsible for, on a page of your own.
The endpoint
Public, no key. CORS is open, so a browser can call it directly, and the rate limit is 30 requests per minute per IP. The full field reference lives under Lists & tools; this page is about putting it on a page without getting it wrong.
{
"entries": [
{
"domain": "*.liorith.net",
"category": "Core",
"check_url": "https://registry.liorith.net/check/liorith.net"
}
],
"categories": ["Core", "Legal", "SysTest"],
"count": 5,
"generated_at": 1788647582078,
"notice": "This list names the domains the Liorith Legal Center is responsible for. …"
}Fetching it
The endpoint answers with Cache-Control: no-store, like every list endpoint, so that a caller always sees the current state. The legal scope changes rarely, though. Cache it on your side for a few minutes: that is well inside the rate limit and survives a short outage on our end.
const ENDPOINT = 'https://api.registry.liorith.net/legal';
export async function fetchLegalScope(category?: string) {
const qs = category ? `?category=${encodeURIComponent(category)}` : '';
const res = await fetch(`${ENDPOINT}${qs}`, {
signal: AbortSignal.timeout(3000),
next: { revalidate: 300 },
});
if (!res.ok) throw new Error(`legal: HTTP ${res.status}`);
return res.json();
}Four things that matter
- On failure, claim nothing
The tempting shortcut is to fall back to an empty list. Your page then states that the Legal Center is responsible for no domain at all, which is a false statement, on a legal page of all places. Show the last known list with its date, or say plainly that the list cannot be reached right now.
- Wildcards are display values, not matchers
A
domainmay read*.liorith.netor**.liorith.net. A leading*.covers subdomains only,**.covers the root and its subdomains, and a bare domain covers both as well. Do not reimplement that matching to answer whether some host falls under the scope. Ask/check?domain=…and readregistered. Thecheck_urlin each entry already points at the human-readable form of exactly that, with the wildcard prefix stripped. - Scope is not operating state
There is deliberately no status in
entries. A domain can be inside the legal scope andsuspendedat the same time; those are different questions, and showing them in one table invites reading one as the other. If you need both, use/domains?legal=true, which carries the state. - An entry may have no category
Not every site is categorised. Such entries appear in
entrieswith an emptycategory, are absent fromcategories, and cannot be selected through?category=. Group them under a heading of your own, the way our page does withuncategorised.
Building the filter
categories holds every category present in the scope and does not shrink when ?category= narrows the entries. That is what makes it usable as a filter: the options stay put, so a visitor can leave a selection again. Categories used only by sites outside the legal scope are absent, so every option you render returns at least one entry.
count, by contrast, refers to the filtered set. If you want to show both, label them apart.
liorith-registry-sdk covers proofs, lookups and badges; a wrapper around a single fetch would be a dependency to maintain for no gain.