Building a Reference Catalog
A practical recipe for embedding a filterable reference catalog on a company website with the REST API.
This guide walks through the standard integration: a catalog page (filterable list) plus detail pages on a company's website. All examples use plain fetch; adapt freely to your stack.
Get the industry navigation
GET /branches/branches returns the company's industries with reference counts — ideal for a category navigation.
const BASE = "https://referenzen.com/api/v1";
const KEY = "YOUR_KEY";
const branches = await fetch(
`${BASE}/branches/branches?apiKey=${KEY}&lang_ID=1`
).then(r => r.status === 204 ? [] : r.json());
// [{ branch_ID, branchname, lft, rgt, referencecount }, …]
The lft/rgt values are nested-set bounds — children of a branch are the entries whose lft/rgt lie inside the parent's range, so you can rebuild the tree client-side.
Render the filter sidebar
GET /references/filters returns ready-to-render filter definitions — label, widget type, and options with hit counts:
const filters = await fetch(
`${BASE}/references/filters?apiKey=${KEY}&lang_ID=1&branch_ID=${branchId}`
).then(r => r.status === 204 ? [] : r.json());
// [{ name: "workfield_ID", label: "Fields of work",
// formtype: "multiselect-checkboxes",
// options: [{ v: 12, d: "BIM Management", c: 8 }, …] }, …]
Each definition's name is the query parameter to send back when the visitor selects options (v values, comma-separated). Company-specific property filters arrive as f{fieldId} names — treat them generically.
Query the catalog
Use GET /references/search for the list — it combines free text, filters, paging, and live facet counts:
const params = new URLSearchParams({
apiKey: KEY,
lang_ID: "1",
query: searchText, // optional free text
branch_ID: String(branchId),
records: "12",
page: String(page),
orderby: "datefrom desc",
getaggregations: "true",
});
// add selected filter values, e.g. params.set("workfield_ID", "12,17")
const res = await fetch(`${BASE}/references/search?${params}`);
const data = res.status === 204
? { total: 0, page: 1, references: [] }
: await res.json();
The response contains total, page, references[] (title, subtitle, location, date, thumbnail, seolabel, …), and aggregations for updating your facet counts (bucket objects use uppercase V = value, C = count).
Prefer a plain list without search? GET /references/referenceprojects returns the same card data with simpler filter parameters — and mode=countonly gives you just the total.
Build the detail page
Fetch one reference with everything on it — media, services, properties, client, partners, awards:
const detail = await fetch(
`${BASE}/references/referenceproject?apiKey=${KEY}&lang_ID=1&reference_ID=${id}`
).then(r => r.status === 204 ? null : r.json());
You can resolve by seolabel instead of reference_ID for clean URLs like /projects/harbor-bridge. Each detail call counts a view in the company's statistics (channel: API).
Handle the edge cases
- 204 everywhere: empty results are
204with an empty body — never callres.json()unconditionally. - Language: offer
lang_ID1/2 only for languages the company actually maintains; a reference not published in a language won't be delivered for it. - Media URLs: use the delivered
thumbnail/file URLs as-is; images are CDN-hosted. - Caching: responses are cache-friendly; a few minutes of caching in your backend keeps the catalog snappy and the load low.
Alternatives to hand-rolling
If a custom build is more than the project needs, consider the catalog widget or the hosted showcase — both give you a catalog without writing API code.