KyroDB docs
TypeScript SDK
Install `kyrodb@1.0.2` from Node/server-side TypeScript code.
Use the TypeScript SDK from Node or other server-side JavaScript code that can safely hold runtime tokens.
npm install kyrodb@1.0.2The SDK is a security-first HTTP client. It validates request bodies, blocks redirects, bounds response size, rejects unsafe freshness integers, and redacts configured secrets in errors.
Install
npm install kyrodb@1.0.2For SDK development:
npm ci
npm run checkConfigure
Get runtime credentials from Console -> Runtime -> Backend environment after the runtime has a ready endpoint. Ready means runtime health is healthy or degraded. Click Create env command and run the generated command from your backend project; it writes .env.kyrodb with KYRODB_BASE_URL, KYRODB_DATA_PLANE_TOKEN, KYRODB_OBSERVABILITY_TOKEN, and non-secret KYRODB_EMBEDDING_DIMENSIONS metadata.
KyroDBClient.fromEnv() requires KYRODB_BASE_URL and KYRODB_DATA_PLANE_TOKEN. It also reads optional KYRODB_OBSERVABILITY_TOKEN, KYRODB_SHADOW_SESSION_ID, and KYRODB_ALLOW_INSECURE_HTTP.
SDKs read environment variables from the process, not from .env.kyrodb directly. For local Node development, run with node --env-file=.env.kyrodb ... or load the same values through your server framework.
node --env-file=.env.kyrodb server.mjsIn deployed environments, copy the generated values into your server, worker, or secret-manager configuration. If you do not want to use fromEnv(), pass those server-side values explicitly:
import { KyroDBClient } from "kyrodb";
const client = new KyroDBClient({
baseUrl: process.env.KYRODB_BASE_URL!,
dataPlaneToken: process.env.KYRODB_DATA_PLANE_TOKEN!,
observabilityToken: process.env.KYRODB_OBSERVABILITY_TOKEN
});Do not use this client directly in a browser. Browser code should call your backend or the KyroDB console BFF, never carry runtime bearer tokens.
Retrieve
import { KyroDBClient, filters } from "kyrodb";
const client = KyroDBClient.fromEnv();
const question = "How do refunds work for annual plans?";
const requestId = "retrieve-req-2026-05-01-001"; // unique per retryable request
const queryEmbedding = await embedUserQuestion(question);
const packet = await client.retrieve(
{
query_embedding: queryEmbedding,
scope: {
tenant_id: "acme",
namespace: "kb"
},
filters: filters.exact("category", "billing"),
top_k: 3,
freshness_mode: "strict",
include_content: true
},
{ idempotencyKey: requestId }
);
if (packet.status === "stale_blocked") {
throw new Error("KyroDB refused to serve stale context");
}queryEmbedding must come from your embedding pipeline and must match the configured runtime connector dimension. The SDK does not generate embeddings.
The returned packet includes:
packet_idtrace_idstatusfreshnessitems- optional
omissions - optional
warnings meta
Idempotency:
retrieve,invalidate,upsertDocument, anddeleteDocumentaccept{ idempotencyKey }as the second argument.ingestChangeEventuses requiredsource_event_idfor retry deduplication.recordFeedbackaccepts only{ signal }as options and does not sendIdempotency-Key.
Observe
Observability and admin methods require KYRODB_OBSERVABILITY_TOKEN or explicit observabilityToken. The SDK uses that token for both surfaces.
const trace = await client.observability.getTrace(packet.trace_id);
const diagnosis = await client.observability.diagnoseTrace(packet.trace_id);
const feedback = await client.observability.getFeedback(packet.trace_id);
const proof = await client.observability.contextProofReport({ recent: 100 });
console.log(trace.status);
console.log(diagnosis.kind, diagnosis.summary);
console.log(feedback);
console.log(proof);Admin evidence methods live under client.admin:
const health = await client.admin.health();
const capture = await client.admin.exportReplayCapture({ recent: 50 });
const bundle = await client.admin.buildProofBundle({ recent: 50 });
const rootCause = await client.admin.buildRootCauseReport({ recent: 50 });
const replayDiff = await client.admin.diffReplayRuns(diffRequest);
const counterfactual = await client.admin.runCounterfactualReplay(counterfactualRequest);
const shadow = await client.admin.createShadowSession({
schema_version: 1,
replay_primer: capture.replay_primer
});Change events
When source knowledge changes outside KyroDB, send a scoped change event. Use stable source_event_id values so retries stay idempotent.
await client.ingestChangeEvent({
target: { type: "namespace", namespace: "kb" },
change_type: "content_updated",
scope: { tenant_id: "acme", namespace: "kb" },
source_event_id: "cms-evt-2026-05-01-001",
timestamp: new Date().toISOString()
});For write-through connectors that certify scoped mutation ACKs:
const updatedDocument = "Updated refund policy.";
const mutationId = "cms-mut-2026-05-01-001"; // unique per retryable mutation
const documentEmbedding = await embedDocument(updatedDocument);
await client.upsertDocument(
{
scope: { tenant_id: "acme", namespace: "kb" },
document: {
id: "billing-policy",
embedding: documentEmbedding,
content: updatedDocument,
metadata: { category: "billing" }
}
},
{ idempotencyKey: mutationId }
);