Query projects in a customer namespace
Keep each independently managed project in its own graph, adopt those graphs
under a customer namespace, and use POST /v1/query/namespace to read them
together. The application catalog and reference dataset features must be enabled
on the deployment. This endpoint requires an environment credential; application
read tokens do not authorize it.
Check GET /version for the namespace_dataset_reads_v1 capability before
calling an older deployment. The capability describes implementation support;
the two feature gates must also be enabled.
Your backend checks the signed-in user’s permission before selecting the customer’s namespace ID from its own records. Environment keys can access every graph in their environment and must stay on your server.
const result = await lbb.sparqlNamespace({ namespace_id: customer.projectsNamespaceId, include_descendants: true, query: ` PREFIX ex: <https://example.com/construction/> SELECT ?project (COUNT(DISTINCT ?risk) AS ?openHighRisks) WHERE { GRAPH ?project { ?risk a ex:Risk ; ex:severity ex:High ; ex:status ex:Open . } } GROUP BY ?project `,});
const rows = JSON.parse(result.results).results.bindings;console.log(rows, result.coverage, result.sources);With Python 0.35.0, use the same request with sparql_namespace:
import json
answer = lbb.sparql_namespace({ "namespace_id": customer.projects_namespace_id, "include_descendants": True, "query": """ PREFIX ex: <https://example.com/construction/> SELECT ?project (COUNT(DISTINCT ?risk) AS ?openHighRisks) WHERE { GRAPH ?project { ?risk a ex:Risk ; ex:severity ex:High ; ex:status ex:Open . } } GROUP BY ?project """,})rows = json.loads(answer["results"])["results"]["bindings"]print(rows, answer["coverage"], answer["sources"])Use await client.sparql_namespace(...) with AsyncLbbClient.
sparql_namespace_model(...) validates the envelope as
models.NamespaceQueryResponse; results remains a SPARQL JSON string.
Python also keeps graph epochs as decimal strings. Both transports retry only
retryable rate limits by default; query execution and transport failures are
surfaced without automatic replay.
The vocabulary is illustrative. The query returns projects with matching risks.
Project graph names are urn:lbb:graph:<graph_id>, and sources maps each name
to its graph ID, exact epoch and pinned publication version. Epochs are decimal
strings, including in JavaScript.
Nested namespaces are included by default. Set include_descendants: false
for graphs owned directly by that namespace. The SDK retains its credential
and environment while omitting the client’s graph and graph-epoch selectors.
Join facts across projects
Section titled “Join facts across projects”The default graph is the RDF set union of the selected graphs. Shared IRIs therefore join across projects, and an identical triple stored in two graphs appears once. Blank nodes remain local to their source graph. Use deliberate, stable entity IRIs to connect company-wide suppliers, standards and rules.
Use GRAPH ?project { ... } to retain project provenance. Set
default_graph: "empty" when every pattern should explicitly name a graph.
An empty namespace stays empty and never falls back to main.
Exact coverage and work limits
Section titled “Exact coverage and work limits”The server selects up to 256 ready catalog graph bindings. Each of two bounded
catalog enumerations scans at most 1,024 directory entries and 16 pages; a
changed selection is refused. Additions concurrent with selection can belong
to a later query. selection_token identifies the exact frozen selection;
it is not an atomic catalog snapshot.
Every selected graph must have a complete published RDF generation. A missing,
unpublished, corrupt, retired or recreated source fails the whole request.
Limits also fail the whole request, with no partial success. Successful
coverage.complete is true and both graph counts match. Sources have independent
publication versions; the answer is not an atomic transaction across projects.
The request has a shared 30-second deadline, 64 MiB logical read allowance, 32 MiB encoded source metadata allowance, one million visited rows, and 10,000 result rows / 16 MiB SPARQL result bytes. Union deduplication and scoped blank-node terms have bounded memory allowances. These limits do not guarantee latency for a customer of a particular size.
This endpoint supports SELECT and ASK over asserted RDF. It does not merge schemas or inference, invoke model-backed search, or accept updates, FROM, FROM NAMED or remote SERVICE. See the HTTP API for the response format and modeling your app for graph and permission boundaries.