OSL API reference
This section defines the public contracts of the OSL engine. What it states is what any client can assume, and what any OSL-conformant engine MUST implement exactly.
For the full object semantics (which primitives exist, their fields) see the specification. Here: how it’s called and what it returns.
Surfaces
Section titled “Surfaces”OSL v1 exposes four separate surfaces:
| Surface | Who consumes it | Shape |
|---|---|---|
| REST | BI tools, apps, dashboards, scripts | HTTP/JSON (Arrow IPC is planned) |
| MCP tools | AI agents (Claude, GPT, Copilot, custom) | tool definitions over the MCP protocol |
| CLI | Developers, CI pipelines | the osl binary (planned) |
| OpenLineage events | Marquez, DataHub, observability | webhook / kafka emitter (planned) |
One consumption endpoint
Section titled “One consumption endpoint”Everything you read goes through a single endpoint — /osl/query. Every
request is exactly one of the five forms of the
OSL-SQL surface:
- Structured —
SELECToverosl.entities.<model>: entities, dimensions and metrics, lowered to the governed SQL seam. - RETRIEVE — governed vector retrieval as a relation source
(
FROM RETRIEVE(...)), served at the subject’s required redaction version. - TRAVERSE — bounded, hop-by-hop graph traversal from anchor keys to a target model.
- Joint (record) — entity-first hydration: one entity’s structured columns plus its content evidence in a single governed call.
- Cross-modal equijoin — the only join across the two planes: structured ×
RETRIEVE, on a sealed, cleartext authoritative entity key.
| Endpoint | Purpose |
|---|---|
POST /osl/query |
The consumption surface — OSL-SQL (osql), raw sql, or the MetricFlow subset |
POST /osl/sample |
Governed content preview — ACL + server-side redaction (not an algebra query) |
GET /osl/domain-map |
The unified domain graph (Entities, metrics, candidates) |
GET /osl/schema |
The compiled semantic view (full view needs an admin role; ?governed=true projects it to the caller’s grants) |
GET /osl/schema/resolve |
Lexicon resolver — business term → canonical FQN (planned, not yet mounted) |
POST /osl/suggest · POST /osl/validate · POST /osl/objects |
Assisted authoring (draft → validate → publish) |
GET /osl/candidates |
Discovery — candidate (not-yet-adopted) entities |
GET /osl/conformance |
Declared conformance levels (currently [] — no complete profile claimed) |
GET /health |
Unauthenticated health check |
MCP tools
Section titled “MCP tools”The optional MCP runner publishes exactly three semantic tools — thin HTTP wrappers that never fabricate identity (each call carries the caller’s own Bearer token):
semantic_query— runs any of the five{osql}forms viaPOST /osl/query.semantic_explain— sends{osql, explain: true}: validates and lowers the plan without executing or returning rows (data-free).semantic_schema—GET /osl/schema?governed=true: only the semantic projection visible to the caller’s chain.
A non-2xx engine response is surfaced as an MCP error with its status and
envelope — a 401/403 never becomes an empty result or a degraded success.
Natural language — an open seam
Section titled “Natural language — an open seam”Natural language is deliberately not part of the normative spec: NL → OSL
translation is a consumer, not a producer. The seam is an open, documented
contract — any agent can plan against GET /osl/schema +
GET /osl/domain-map, validate with {osql, explain: true}, and execute with
POST /osl/query, getting the same server-side enforcement as every other
caller (the LLM never sees data during planning, only schema + question).
OpenDome’s own implementation of that loop, osl-ask, ships in the
Enterprise companion — it is not in the OSS tree, and you can replace it with
your own translator without touching OSL. The contract is specified in
docs/osl/natural-language.md.
API versioning
Section titled “API versioning”/osl/ is the v1 root. A breaking v2 would live at /osl/v2/ while /osl/
keeps serving the v1 contract for at least two consecutive minor versions.
Endpoints MAY add optional response fields within v1.x; clients MUST
ignore unrecognized fields.