Qirava DMS docs
Self-describing API: /api/spec
GET /api/spec returns a self-describing catalog of the entire public API surface: every callable function, its access scope, its input and output fields, and the error codes it can return — plus the uniform envelope shape and the full error-code table. The catalog is built once at startup from static metadata joined to the live function registry, cached as raw bytes, and served verbatim, so it costs nothing per request. Crucially it documents only keys, scopes, and field shapes; it reads no row data from any system table and reflects nothing from the request body. This page explains exactly what is in the catalog, how it is assembled, and how to read it, transcribed from src/functions/api/mod.rs and src/functions/schemas.rs.
What the catalog is#
The catalog is a single JSON document describing the public function surface of the DMS. It is the machine-readable answer to "what can I call, what does it take, what does it return, and how can it fail?". A client or tooling can fetch it once and generate stubs, validate inputs, or render an API explorer.
It is assembled by build_catalog(rt), which folds every function group's static API_META table (plus the auth group's) into one document, JOINs the live registry by function key to fill each entry's real scope/origin/fifo, and emits the single-source error-code table and the documented envelope shape.
Top-level shape#
The catalog document has four top-level keys.
- qirava_api_version
- The stable wire version of the catalog. Currently "1" (the
API_VERSIONconstant). - envelope
- The documented uniform response shape — an object with
okanderrorexample skeletons, so a reader sees exactly how success and failure responses are shaped. - error_codes
- An array of
{ "code", "http" }— the eight distinct stable error codes and their HTTP statuses, derived fromcode_status. - categories
- An array of
{ "name", "functions" }— the function groups, each with the list of its documented functions.
{
"qirava_api_version": "1",
"envelope": {
"ok": { "error": null, "data": "<value>",
"root": { "took_us": "<int>", "request_id": "<string>" } },
"error": { "error": { "code": "<stable_code>", "message": "<string>" },
"data": null,
"root": { "took_us": "<int>", "request_id": "<string>" } }
},
"error_codes": [ ... ],
"categories": [ ... ]
}Fetching the catalog#
Request
GET /api/spec HTTP/1.1
Host: localhostResponse
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{"error":null,"data":{"qirava_api_version":"1","envelope":{...},"error_codes":[{"code":"ok","http":200}, ... ],"categories":[ ... ]},"root":{"took_us":<int>,"request_id":"<hex>"}}Output
// The route is OutputKind::RawJson, so the catalog document is
// embedded UNESCAPED as the `data` value of the uniform envelope.
// The whole envelope is wrapped by the worker, so `root` here
// carries took_us + request_id.The catalog is exposed as a public route api.spec (GET /api/spec, handler system.api_spec) with OutputKind::RawJson. The handler simply returns the cached bytes; the worker embeds them as the envelope's data value.
error_codes block#
distinct_error_codes() iterates every ResponseCode variant through code_status and dedups by stable code, so the catalog publishes exactly the eight distinct codes. This is the same set used by the OpenAPI projection's error enum and the worker's own mapping.
"error_codes": [
{ "code": "ok", "http": 200 },
{ "code": "workers_busy", "http": 503 },
{ "code": "not_found", "http": 404 },
{ "code": "forbidden", "http": 403 },
{ "code": "bad_request", "http": 400 },
{ "code": "rate_limited", "http": 429 },
{ "code": "function_failed", "http": 422 },
{ "code": "internal", "http": 500 }
]categories and functions#
Functions are grouped by category, preserving table order within a category. The categories, in catalog order, are: planner, read, write, search, graph, vector, inline, auth. Each function object joins the static ApiMeta (key/summary/description/input/output/error_codes) with the live registry's FunctionInfo (scope/origin/fifo) looked up by key.
- key
- The public function key (e.g.
qql.read.key), matching the registered root. - scope
- From the live registry: one of
public,internal_global,internal_scoped,internal_private. Public catalog entries arepublic. - origin
- From the live registry:
builtinoruser_defined. - fifo
- Boolean from the live registry: whether public calls with the same execution key pin/serialize (mutating roots are typically fifo).
- summary
- One-line human summary (from
ApiMeta). - description
- One-to-two sentence description (from
ApiMeta). - input
- Array of
{ name, type, required }— the request record fields. - output
- Array of
{ name, type, required }— the response record fields. - error_codes
- Array of stable code strings this function may return (a subset of the eight).
Request
// Located at: data.categories[name="read"].functions[0]Response
{
"key": "qql.read.key",
"scope": "public",
"origin": "builtin",
"fifo": false,
"summary": "Fetch a single row by primary key.",
"description": "Plans the query and fetches the row whose primary key matches the request, returning at most one row.",
"input": [
{ "name": "query", "type": "string", "required": true },
{ "name": "key", "type": "string", "required": true }
],
"output": [
{ "name": "rows", "type": "list<record>", "required": true },
{ "name": "count", "type": "int", "required": true }
],
"error_codes": [ "bad_request", "function_failed", "internal" ]
}Output
// scope/origin/fifo came from the live registry JOIN.
// summary/description/input/output/error_codes came from the
// static ApiMeta table in src/functions/read/schemas.rs.How a function entry is assembled (the JOIN)#
per-group API_META tables live FunctionRuntime registry
(planner/read/write/search/ (rt.list_public_functions() +
graph/vector/inline/auth) rt.list_builtin_functions())
key, summary, desc, key -> { scope, origin, fifo }
input[], output[], error_codes[]
\ /
\------------ JOIN by key ----------/
|
function_json(meta, info)
|
grouped by category, in table order
|
+ error_codes (from code_status) + envelope shape
+ qirava_api_version
|
build_catalog(rt) -> String
|
cached as Arc<[u8]> at startup, served verbatimIf the registry lookup misses for a documented key (it should not — a completeness test guards every registered root + auth key), the entry defaults to scope: public, origin: builtin, fifo: false.
Where the metadata lives#
Each function group owns a schemas.rs with a const API_META: &[ApiMeta] table. The ApiMeta and FieldSpec types are defined in src/functions/schemas.rs. Because they are all &'static const data, the tables compile in and never allocate at request time.
| Group | Metadata table |
|---|---|
| planner | src/functions/planner/schemas.rs :: API_META |
| read | src/functions/read/schemas.rs :: API_META |
| write | src/functions/write/schemas.rs :: API_META |
| search | src/functions/search/schemas.rs :: API_META |
| graph | src/functions/graph/schemas.rs :: API_META |
| vector | src/functions/vector/schemas.rs :: API_META |
| inline | src/functions/inline/schemas.rs :: API_META |
| auth | src/functions/auth/schemas.rs :: API_META |
FieldSpec::req(name, ty) and FieldSpec::opt(name, ty) are the const constructors for required/optional fields; ty is a logical type string such as "string", "int", "record", or "list<record>".
Integrity guarantees (tests)#
The catalog module ships tests that keep the catalog honest and complete. These are part of the contract, not decoration.
- every_root_and_auth_key_has_exactly_one_api_meta — every registered public root and every auth key is documented exactly once.
- no_api_meta_documents_an_unknown_key — no stale or typo'd metadata documents a function that does not exist.
- every_api_meta_error_code_is_a_valid_stable_code — every error code listed by a function is one of the eight stable codes from
code_status. - response_code_enumeration_is_complete — 11 internal
ResponseCodevariants collapse to 8 distinct stable codes; guards that the enumeration stays in lock-step. - catalog_joins_registry_and_is_well_formed — the built catalog contains the version, categories, error_codes, envelope, a known public root joined to its live scope, and all eight error codes with correct HTTP statuses.