@hydradb/sdk
v2.1.0
Published
The official TypeScript SDK for the Hydra DB platform.
Downloads
2,153
Readme
HydraDB TypeScript SDK
The official TypeScript/JavaScript SDK for HydraDB — a managed retrieval engine that combines vector search, full‑text search, and a knowledge graph behind a single API.
- Package:
@hydradb/sdk - Client class:
HydraDBClient - Version:
2.1.0(API version2) - Docs: https://docs.hydradb.com
- Runtime: Node.js 18+ (works with any
fetch-capable runtime)
Table of contents
- Installation
- Quick start
- Client configuration
- Core concepts
- Responses & raw access
- Endpoints
- Error handling
- Advanced
Installation
npm install @hydradb/sdk
# or: pnpm add @hydradb/sdk / yarn add @hydradb/sdkQuick start
import { HydraDBClient } from "@hydradb/sdk";
const client = new HydraDBClient({
token: "YOUR_API_KEY", // bearer token
});
// Run a hybrid search over a database ("tenant")
const result = await client.query({
query: "What is our refund policy?",
database: "acme-corp",
type: "knowledge",
maxResults: 5,
});
console.log(result.data);Every method returns an awaitable HttpResponsePromise. await-ing it resolves to the parsed
response body (a HandlerEnvelope… object whose payload is on .data). See
Responses & raw access.
Client configuration
import { HydraDBClient, HydraDBEnvironment } from "@hydradb/sdk";
const client = new HydraDBClient({
token: "YOUR_API_KEY",
apiVersion: "2", // optional, defaults to "2"
environment: HydraDBEnvironment.Default, // https://api.hydradb.com
// baseUrl: "https://api.hydradb.com", // override for self-hosted / staging
timeoutInSeconds: 60, // default 60
maxRetries: 2, // default 2
headers: { "X-Custom-Header": "value" }, // sent on every request
});| Option | Type | Default | Notes |
| ------------------ | ------------------------------------- | ------------------------ | ----- |
| token | string \| () => string \| Promise | – | Bearer token. Accepts a supplier for dynamic/refreshing tokens. |
| apiVersion | string | "2" | Sets the API-Version header. |
| environment | HydraDBEnvironment \| string | Default | Default → https://api.hydradb.com. |
| baseUrl | string | – | Explicit URL; overrides environment. |
| timeoutInSeconds | number | 60 | Per‑request timeout. |
| maxRetries | number | 2 | Automatic retries on transient failures. |
| headers | Record<string, string> | – | Extra headers on every request. |
| fetch | typeof fetch | runtime default | Custom fetch implementation. |
| logging | LogConfig \| Logger | silent | SDK logging. |
Note: all request fields use camelCase in TypeScript (e.g.
subTenantId,maxResults); the SDK maps them to the API's snake_case wire format for you.
Core concepts
Database vs. Collection (tenant vs. sub‑tenant). HydraDB v2 renamed the isolation scopes:
| v2 name (canonical) | v1 alias (deprecated, still accepted) | Meaning |
| ------------------- | ------------------------------------- | ------- |
| database | tenantId | Top‑level isolation boundary. |
| collection | subTenantId | A namespace within a database. |
The server’s TenantAliases middleware reconciles the two, so you can pass either — but new
code should use database / collection. The legacy aliases will be removed in a future release.
Corpora (type). Data is split into two corpora you can target independently:
"knowledge" (documents), "memory" (agent memories), or "all".
Responses & raw access
await-ing any call gives you the parsed body:
const res = await client.databases.list();
console.log(res.data); // the payload
console.log(res.meta); // request metadataTo also get the HTTP status and headers, call .withRawResponse():
const { data, rawResponse } = await client.query({ query: "hi", database: "acme-corp" })
.withRawResponse();
console.log(rawResponse.status);
console.log(rawResponse.headers.get("x-request-id"));
console.log(data);Endpoints
query — unified retrieval
POST /query → HandlerEnvelopeSearchV2RetrievalResult
The single retrieval endpoint. Dispatches across corpus (type) and retrieval method
(queryBy), optionally enriching results with knowledge‑graph context.
const result = await client.query({
query: "How do I rotate API keys?",
database: "acme-corp", // v2 name for the tenant scope
type: "knowledge", // "knowledge" | "memory" | "all"
queryBy: "hybrid", // "hybrid" | "text"
mode: "auto", // "fast" | "thinking" | "auto"
operator: "or", // "or" | "and" | "phrase"
maxResults: 10,
numRelatedChunks: 3,
graphContext: true, // include KG context (default true)
recencyBias: 0.2,
metadataFilters: { // exact-match on tenant/document metadata
department: "security",
additional_metadata: { author: "ada" },
},
});
console.log(result.data);Scoping to specific collections (preferred over the deprecated subTenantIds):
// Equal weighting across collections
await client.query({ query: "pricing", database: "acme-corp", collections: ["eu", "us"] });
// Weighted ranking (one decimal place max)
await client.query({ query: "pricing", database: "acme-corp", collections: { eu: 1.0, us: 0.5 } });Scoping to specific source IDs — ids applies a hard source_id in [...] pre‑filter; if
nothing matches it returns empty rather than widening to the whole corpus:
await client.query({ query: "onboarding", database: "acme-corp", ids: ["doc_123", "doc_456"] });Key fields (SearchQueryRequest):
| Field | Type | Notes |
| ------------------------- | ----------------------------------- | ----- |
| query | string | The search text. |
| database | string | Tenant scope (v2). Alias: tenantId. |
| collection / collections | string / string[] \| Record<string, number> | Sub‑tenant scope. Prefer over subTenantId(s). |
| type | "knowledge" \| "memory" \| "all" | Corpus to query. |
| queryBy | "hybrid" \| "text" | Retrieval method. |
| mode | "fast" \| "thinking" \| "auto" | Recall mode. |
| operator | "or" \| "and" \| "phrase" | Text‑match operator. |
| maxResults | number | Result cap. |
| numRelatedChunks | number | Neighboring chunks to attach. |
| graphContext | boolean | Include KG context. Default true. |
| queryApps | boolean | App‑aware knowledge retrieval. |
| queryForcefulRelations | boolean | Force relation expansion. Default true. |
| metadataFilters | Record<string, unknown> | Exact‑match (nest doc metadata under additional_metadata). |
| recencyBias | number | Boost newer sources. |
| ids | string[] | Restrict to specific source IDs. |
Context (client.context)
Everything about the data inside a database: ingesting, listing, inspecting, updating metadata, checking processing status, reading graph relations, and deleting.
context.ingest
POST /context/ingest (multipart) → HandlerEnvelopeIngestionV2SourceUploadResponse
Ingest knowledge documents or memories. documents is a file upload; the other structured
fields are JSON strings.
import { createReadStream } from "fs";
// Ingest a document file
const res = await client.context.ingest({
tenantId: "acme-corp", // required
documents: createReadStream("handbook.pdf"),
subTenantId: "hr",
type: "knowledge",
// documentMetadata is a JSON *array* — one object per uploaded file.
documentMetadata: JSON.stringify([{ title: "Employee Handbook", author: "HR" }]),
upsert: "true", // form field is a string
});
console.log(res.data);
// Ingest memories (no file). Each item needs "text" (or "user_assistant_pairs").
await client.context.ingest({
tenantId: "acme-corp",
memories: JSON.stringify([{ text: "User prefers dark mode" }]),
type: "memory",
});| Field | Type | Notes |
| ------------------ | ------------------------ | ----- |
| tenantId | string (required) | Database. |
| documents | Uploadable | File upload (stream, Blob, Buffer, etc.). |
| memories | string | JSON array string; each item needs text (or user_assistant_pairs). |
| documentMetadata | string | JSON array string of per‑document metadata — one object per uploaded file (count must match). |
| appKnowledge | string | App‑knowledge payload. |
| graphPayload | string | Pre‑computed graph payload. |
| subTenantId | string | Collection. |
| type | string | "knowledge" or "memory". |
| upsert | string | "true" to upsert on existing IDs. |
context.list
POST /context/list → HandlerEnvelopeListV2SourceListResponse
List sources or memories (IDs + metadata) for a database, with filtering and pagination.
const res = await client.context.list({
database: "acme-corp",
collection: "hr",
type: "knowledge",
page: 1,
pageSize: 50,
includeFields: ["title", "type", "timestamp"],
filters: {
metadata: { department: "finance" }, // tenant/source metadata
additionalMetadata: { author: "ada" }, // document metadata
sourceFields: { type: "pdf" }, // well-known source fields
},
});
for (const source of res.data.sources ?? []) {
console.log(source);
}context.inspect
GET /context/inspect → HandlerEnvelopeFetchV2SourceFetchResponse
Fetch a single ingested source: its content, inferred content, and a presigned download URL.
const res = await client.context.inspect({
id: "doc_1234", // required — source ID
tenantId: "acme-corp", // required
subTenantId: "hr",
expirySeconds: 3600, // presigned URL lifetime
mode: "both", // fetch mode: "content", "url", or "both"
});
console.log(res.data);context.status
GET /context/status → HandlerEnvelopeIngestionV2BatchProcessingStatus
Check processing status for one or more source IDs.
// Single source
await client.context.status({ tenantId: "acme-corp", id: "doc_1234", subTenantId: "hr" });
// Batch
const res = await client.context.status({
tenantId: "acme-corp",
ids: ["doc_1", "doc_2", "doc_3"],
});
console.log(res.data);context.relations
GET /context/relations → HandlerEnvelopeGraphGraphRelationsResponse
Return knowledge‑graph relations for a whole database or a single source.
const res = await client.context.relations({
tenantId: "acme-corp", // required
subTenantId: "hr",
id: "doc_1234", // omit for database-wide relations
type: "knowledge", // "knowledge" | "memory"
limit: 100,
cursor: 0, // pagination cursor
});
console.log(res.data);context.updateSourceMetadata
PATCH /context/sources/{sourceId}/metadata → HandlerEnvelope…MetadataEditResult
Merge/upsert tenantMetadata and additionalMetadata for one source. subTenantId is
required by the server.
const res = await client.context.updateSourceMetadata({
sourceId: "doc_1234", // required — path param
tenantId: "acme-corp",
subTenantId: "hr",
// tenantMetadata keys must be declared in the database's tenant_metadata_schema
// (and match the declared type). Use additionalMetadata for free-form fields.
tenantMetadata: { department: "finance" },
additionalMetadata: { author: "ada", tags: ["policy", "2026"], reviewed: true },
});
console.log(res.data);Note: although the SDK exposes a
documentMetadataparameter here, this endpoint rejects it (HTTP 400 "document_metadata is not accepted; use additional_metadata"). Put per-document fields inadditionalMetadatainstead.
context.delete
DELETE /context → HandlerEnvelopeSourcesMemoryDeleteResponse
Delete one or more sources or memories by ID.
const res = await client.context.delete({
database: "acme-corp",
collection: "hr",
ids: ["doc_1234", "doc_5678"],
type: "knowledge",
});
console.log(res.data);Databases (client.databases)
Manage databases (tenants) and inspect their collections, stats, and provisioning status.
databases.create
POST /databases → HandlerEnvelopeTenantsTenantCreateAcceptedResponse
Create a new database, optionally with a custom metadata schema for its collections.
const res = await client.databases.create({
database: "acme-corp",
embeddingsDimension: 1536,
isEmbeddingsTenant: true,
tenantMetadataSchema: [
{
name: "department",
dataType: "VARCHAR", // BOOL | INT8..INT64 | FLOAT | DOUBLE | VARCHAR | JSON | ARRAY
maxLength: 128,
enableMatch: true,
},
{ name: "priority", dataType: "INT32" },
],
});
console.log(res.data);Creation is asynchronous — poll
databases.statusuntil infrastructure is provisioned before ingesting.
databases.list
GET /databases → HandlerEnvelopeTenantsTenantIdsResponse
List all databases for the authenticated user. Takes no request body.
const res = await client.databases.list();
console.log(res.data);databases.collections
GET /databases/collections → HandlerEnvelopeTenantsSubTenantIdsResponse
List all collections within a database.
const res = await client.databases.collections({ database: "acme-corp" });
console.log(res.data);databases.stats
GET /databases/stats → HandlerEnvelopeTenantsTenantStatsResponse
Get collection statistics for a database.
const res = await client.databases.stats({ database: "acme-corp" });
console.log(res.data);databases.status
GET /databases/status → HandlerEnvelopeTenantsInfraStatusResponseV2
Check infrastructure provisioning status for a database.
const res = await client.databases.status({ database: "acme-corp" });
console.log(res.data);databases.delete
DELETE /databases → HandlerEnvelopeTenantsTenantDeleteResponse
Delete a database and all associated data.
const res = await client.databases.delete({ database: "acme-corp" });
console.log(res.data);Webhooks (client.webhooks)
Register a single indexing webhook per org and inspect/replay its deliveries.
webhooks.register
POST /webhooks/indexing → HandlerEnvelopeWebhooksWebhookRegisterResponse
Register (or update) the indexing webhook for this API key’s org.
const res = await client.webhooks.register({
url: "https://example.com/hooks/hydradb",
eventTypes: ["indexing.status_changed"], // the only supported event type
signingSecret: "whsec_at_least_16_chars", // must be >= 16 characters
});
console.log(res.data);webhooks.get
GET /webhooks/indexing → HandlerEnvelopeWebhooksWebhookGetResponse
Fetch the currently registered webhook. Takes no request body.
const res = await client.webhooks.get();
console.log(res.data);webhooks.test
POST /webhooks/indexing/test → HandlerEnvelopeWebhooksWebhookTestResponse
Send a test delivery to the registered endpoint.
const res = await client.webhooks.test();
console.log(res.data);webhooks.delete
DELETE /webhooks/indexing → HandlerEnvelopeWebhooksWebhookDeleteResponse
Remove the registered webhook.
const res = await client.webhooks.delete();
console.log(res.data);webhooks.listDeliveries
GET /webhooks/indexing/deliveries → HandlerEnvelopeWebhooksDeliveryListResponse
List recent webhook deliveries, with filtering and cursor pagination.
const res = await client.webhooks.listDeliveries({
limit: 50,
cursor: undefined, // pass the previous page's cursor to continue
status: "failed", // filter by delivery status
});
console.log(res.data);webhooks.getDelivery
GET → HandlerEnvelopeWebhooksDeliveryItem
Fetch a single delivery by ID.
const res = await client.webhooks.getDelivery({ deliveryId: "dlv_1234" });
console.log(res.data);webhooks.retryDelivery
POST → HandlerEnvelopeWebhooksRetryResponse
Re‑attempt a failed delivery.
const res = await client.webhooks.retryDelivery({ deliveryId: "dlv_1234" });
console.log(res.data);Error handling
Non‑2xx responses throw typed errors. Each carries statusCode, the parsed body, and the
rawResponse. All extend HydraDBError.
import {
HydraDBClient,
HydraDB, // namespace with the typed error classes
HydraDBError,
} from "@hydradb/sdk";
const client = new HydraDBClient({ token: "YOUR_API_KEY" });
try {
await client.databases.status({ database: "does-not-exist" });
} catch (err) {
if (err instanceof HydraDB.NotFoundError) {
console.error("not found:", err.body);
} else if (err instanceof HydraDBError) {
console.error(`API error ${err.statusCode}:`, err.body);
} else {
throw err;
}
}Typed error classes (under the HydraDB namespace): BadRequestError (400),
ForbiddenError (403), NotFoundError (404), ConflictError (409),
UnprocessableEntityError (422), InternalServerError (500). Network/timeout failures throw
HydraDBTimeoutError / HydraDBError.
Advanced
Per-request options (timeouts, retries, abort)
Every method accepts a second requestOptions argument that overrides client defaults for
that call.
const controller = new AbortController();
await client.query(
{ query: "hello", database: "acme-corp" },
{
timeoutInSeconds: 30,
maxRetries: 3,
apiVersion: "2",
headers: { "X-Trace-Id": "abc123" },
abortSignal: controller.signal,
},
);Passthrough fetch
For endpoints not yet wrapped by the SDK, client.fetch issues a request using the SDK's
configured auth, retries, and logging. Relative paths resolve against the configured base URL.
const response = await client.fetch("/some/new/endpoint", {
method: "POST",
body: JSON.stringify({ hello: "world" }),
});
console.log(await response.json());Custom fetch & logging
import { HydraDBClient } from "@hydradb/sdk";
import nodeFetch from "node-fetch";
const client = new HydraDBClient({
token: "YOUR_API_KEY",
fetch: nodeFetch as unknown as typeof fetch,
logging: { level: "debug" },
});Endpoint reference
| Group | Method | HTTP | Description |
| --------- | ----------------------- | ------------------------------------------ | ----------- |
| — | query | POST /query | Unified hybrid/text retrieval with optional graph context. |
| context | ingest | POST /context/ingest | Ingest documents or memories (multipart). |
| context | list | POST /context/list | List sources/memories with filters + pagination. |
| context | inspect | GET /context/inspect | Fetch a source’s content + presigned URL. |
| context | status | GET /context/status | Processing status for one or many source IDs. |
| context | relations | GET /context/relations | KG relations for a database or source. |
| context | updateSourceMetadata | PATCH /context/sources/{id}/metadata | Merge/upsert metadata for a source. |
| context | delete | DELETE /context | Delete sources/memories by ID. |
| databases | create | POST /databases | Create a database with optional schema. |
| databases | list | GET /databases | List all databases. |
| databases | collections | GET /databases/collections | List collections in a database. |
| databases | stats | GET /databases/stats | Collection statistics. |
| databases | status | GET /databases/status | Infra provisioning status. |
| databases | delete | DELETE /databases | Delete a database and its data. |
| webhooks | register | POST /webhooks/indexing | Register/update the org indexing webhook. |
| webhooks | get | GET /webhooks/indexing | Get the registered webhook. |
| webhooks | test | POST /webhooks/indexing/test | Send a test delivery. |
| webhooks | delete | DELETE /webhooks/indexing | Remove the webhook. |
| webhooks | listDeliveries | GET /webhooks/indexing/deliveries | List recent deliveries. |
| webhooks | getDelivery | GET | Fetch one delivery by ID. |
| webhooks | retryDelivery | POST | Retry a failed delivery. |
This SDK is generated from the HydraDB API definition. For the full type reference see the
api/ directory or https://docs.hydradb.com.
