Skip to content

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_VERSION constant).
envelope
The documented uniform response shape — an object with ok and error example 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 from code_status.
categories
An array of { "name", "functions" } — the function groups, each with the list of its documented functions.
json
{
  "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: localhost

Response

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.

json
"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 are public.
origin
From the live registry: builtin or user_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 verbatim
build_catalog: static metadata JOIN live registry, cached once

If 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.

GroupMetadata table
plannersrc/functions/planner/schemas.rs :: API_META
readsrc/functions/read/schemas.rs :: API_META
writesrc/functions/write/schemas.rs :: API_META
searchsrc/functions/search/schemas.rs :: API_META
graphsrc/functions/graph/schemas.rs :: API_META
vectorsrc/functions/vector/schemas.rs :: API_META
inlinesrc/functions/inline/schemas.rs :: API_META
authsrc/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 ResponseCode variants 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.