TypeScript SDK
The get-db9 SDK provides typed TypeScript access to DB9 databases — provisioning, SQL execution, filesystem operations, branching, and token management.
When to Use the SDK
Section titled “When to Use the SDK”| Scenario | Recommended tool |
|---|---|
| One-liner database provisioning in a script or test | SDK — instantDatabase() |
| Programmatic fleet management (create, branch, delete) | SDK — createDb9Client() |
| File read/write from Node.js (RAG, ingestion) | SDK — client.fs.* |
| Interactive SQL from a terminal | CLI — db9 db sql (CLI Reference) |
| ORM or driver connection to an existing database | Raw pgwire — use the connection string (Connect) |
| Agent onboarding (Codex, Claude Code) | CLI — db9 onboard (Agent Workflows) |
Installation
Section titled “Installation”Runtime requirement: Node.js 18+ (native fetch). TypeScript 5+ for full type exports.
npm install get-db9Also available via yarn add get-db9, pnpm add get-db9, or bun add get-db9.
The SDK shares the credential store (~/.db9/credentials) with the db9 CLI. If you have logged in via the CLI, the SDK picks up the token automatically.
Quick Start
Section titled “Quick Start”instantDatabase() creates or reuses a database by name. If no name is provided, it defaults to "default".
import { instantDatabase } from 'get-db9';
const db = await instantDatabase({ name: 'myapp', seed: 'CREATE TABLE users (id SERIAL PRIMARY KEY, email TEXT)'});
console.log(db.databaseId);console.log(db.connectionString);console.log(db.adminUser, db.adminPassword);console.log(db.state, db.createdAt);Prerequisite: The SDK requires a valid token in
~/.db9/credentialsor passed viaDb9ClientOptions.token. If no token is available, the client throws an error. Rundb9 loginordb9 create(which auto-registers an anonymous account) before using the SDK, or pass a token explicitly.
Result shape:
interface InstantDatabaseResult { databaseId: string; connectionString: string; adminUser: string; adminPassword: string; state: string; createdAt: string;}instantDatabase(options?)
Section titled “instantDatabase(options?)”High-level API that wraps createDb9Client(), checks for an existing database by name, creates one if missing, and optionally executes seed SQL. Seed SQL runs only on initial creation — if the database already exists, seed is skipped.
function instantDatabase( options?: InstantDatabaseOptions): Promise<InstantDatabaseResult>;| Option | Type | Description |
|---|---|---|
name | string | Database name. Default: 'default'. |
baseUrl | string | Override API endpoint. Default: https://api.db9.ai or DB9_API_URL env. |
fetch | FetchFn | Custom fetch implementation. |
credentialStore | CredentialStore | Token load/save strategy. |
seed | string | SQL text executed via client.databases.sql() on creation only. |
seedFile | string | SQL file content executed via client.databases.sqlFile() on creation only. |
timeout | number | Request timeout in milliseconds. |
maxRetries | number | Retry count for failed requests (capped at 3). |
retryDelay | number | Delay between retries in milliseconds. |
const db = await instantDatabase({ name: 'analytics', seedFile: ` CREATE TABLE events ( id BIGSERIAL PRIMARY KEY, user_id TEXT NOT NULL, created_at TIMESTAMP DEFAULT NOW() ); `});createDb9Client(options?)
Section titled “createDb9Client(options?)”Low-level typed client exposing grouped APIs: auth, tokens, databases, and fs.
The client lazy-loads the token from the credential store on the first protected call. If no token is found, it throws Db9Error (status 401). Use db9 login or pass a token via options.token before calling protected methods.
function createDb9Client(options?: Db9ClientOptions): Db9Client;| Option | Type | Description |
|---|---|---|
baseUrl | string | Default: https://api.db9.ai (or DB9_API_URL env). |
token | string | Bearer token; skips credential store lookup. |
fetch | FetchFn | Custom HTTP implementation. |
credentialStore | CredentialStore | Load/save token state. |
timeout | number | Request timeout in milliseconds. |
maxRetries | number | Retry count for failed requests (capped at 3). |
retryDelay | number | Delay between retries in milliseconds. |
WebSocket | WebSocketConstructor | Override WebSocket for client.fs operations (see Filesystem). |
wsPort | number | Override the fs9 WebSocket port (default: 5480). |
import { createDb9Client, MemoryCredentialStore } from 'get-db9';
const client = createDb9Client({ baseUrl: 'https://api.db9.ai', credentialStore: new MemoryCredentialStore()});Authentication (client.auth)
Section titled “Authentication (client.auth)”me(): Promise<CustomerResponse>— Get current user profile
The SDK itself does not handle login or registration. Use the CLI for auth:
# Zero-setup trial (auto creates anonymous account + token)db9 create --name quickstart
# Upgrade anonymous account to verified SSO identitydb9 claim
# Human operator login (browser-based)db9 login
# API key login (CI/CD, agents)db9 login --api-key <KEY>
# Create an automation tokendb9 token create --name my-agent --expires-in-days 365
# Agent runtimeexport DB9_API_KEY=<token>Once authenticated via CLI, the SDK picks up the stored token automatically.
Token Management (client.tokens)
Section titled “Token Management (client.tokens)”Create, inspect, and revoke API tokens for CI/CD and programmatic access.
create(req: CreateTokenRequest): Promise<CreateTokenResponse>— Create named token with optional expirylist(): Promise<TokenResponse[]>revoke(tokenId: string): Promise<MessageResponse>
const newToken = await client.tokens.create({ name: 'ci-deploy', expires_in_days: 90});console.log(newToken.token); // Store in secret manager
const tokens = await client.tokens.list();for (const token of tokens) { console.log(token.id, token.name, token.created_at, token.expires_at);}
await client.tokens.revoke(tokens[0].id);Database Management (client.databases)
Section titled “Database Management (client.databases)”Core lifecycle APIs: create, list, get, delete, reset password, retrieve credentials, create connect tokens, and read observability metrics.
create(req: CreateDatabaseRequest): Promise<DatabaseResponse>list(): Promise<DatabaseResponse[]>get(databaseId: string): Promise<DatabaseResponse>delete(databaseId: string): Promise<MessageResponse>resetPassword(databaseId: string): Promise<CustomerPasswordResetResponse>credentials(databaseId: string): Promise<CustomerPasswordResetResponse>— Get stored admin credentials without resettingconnectToken(databaseId: string, role?: string): Promise<CreateConnectTokenResponse>— Create a short-lived connect token (10-min TTL)observability(databaseId: string): Promise<TenantObservabilityResponse>
const db = await client.databases.create({ name: 'billing', region: 'us-west', admin_password: 'StrongAdminPass1'});
const all = await client.databases.list();const current = await client.databases.get(db.id);
const rotated = await client.databases.resetPassword(db.id);const creds = await client.databases.credentials(db.id);const metrics = await client.databases.observability(db.id);
// Short-lived connect token for psql/ORM usageconst connectToken = await client.databases.connectToken(db.id);console.log(connectToken.host, connectToken.user, connectToken.token);
await client.databases.delete(db.id);For programmatic provisioning patterns, see Provisioning.
SQL Execution
Section titled “SQL Execution”Execute SQL strings or SQL file content through the customer API. Both methods return SqlResult.
sql(databaseId: string, query: string): Promise<SqlResult>sqlFile(databaseId: string, fileContent: string): Promise<SqlResult>
const result = await client.databases.sql( databaseId, 'SELECT id, email FROM users ORDER BY id LIMIT 10');
console.log(result.columns);console.log(result.rows);console.log(result.row_count, result.command, result.error);
const fromFile = await client.databases.sqlFile(databaseId, ` CREATE TABLE audit_log (id BIGSERIAL PRIMARY KEY, event TEXT); INSERT INTO audit_log(event) VALUES ('created');`);SqlResult Field | Type | Description |
|---|---|---|
columns | ColumnInfo[] | Column metadata for result rows. |
rows | unknown[][] | Result values matrix. |
row_count | number | Rows affected/returned. |
command | string | Executed command label (SELECT, INSERT, etc.). |
error | string | SqlErrorDetail | Structured error with message, code, detail, hint, and position. |
Schema and Dump
Section titled “Schema and Dump”Introspect schema objects or export SQL dump payloads.
schema(databaseId: string): Promise<SchemaResponse>dump(databaseId: string, req?: DumpRequest): Promise<DumpResponse>
const schema = await client.databases.schema(databaseId);for (const table of schema.tables) { console.log(table.schema, table.name);}
const ddlOnly = await client.databases.dump(databaseId, { ddl_only: true });console.log(ddlOnly.object_count);console.log(ddlOnly.sql);Migrations
Section titled “Migrations”Apply SQL migrations with checksums and inspect migration history.
applyMigration(databaseId: string, req: MigrationApplyRequest): Promise<MigrationApplyResponse>listMigrations(databaseId: string): Promise<MigrationMetadata[]>
await client.databases.applyMigration(databaseId, { name: '20260218_add_users', sql: 'CREATE TABLE users (id SERIAL PRIMARY KEY, email TEXT NOT NULL);', checksum: 'f0b9c43b'});
const applied = await client.databases.listMigrations(databaseId);for (const migration of applied) { console.log(migration.name, migration.applied_at, migration.checksum);}Branching
Section titled “Branching”Create a database branch from an existing database. Branch creation starts in CLONING state — poll with get() until it reaches ACTIVE or CREATE_FAILED.
branch(databaseId: string, req: BranchRequest): Promise<DatabaseResponse>
const featureDb = await client.databases.branch(databaseId, { name: 'feature-auth'});
let current = featureDb;while (current.state === 'CLONING') { await new Promise((resolve) => setTimeout(resolve, 1000)); current = await client.databases.get(featureDb.id);}
if (current.state === 'CREATE_FAILED') { throw new Error('Branch clone failed');}
console.log('Branch ready:', current.id, current.name);For branch workflow patterns, see Multi-Tenant Patterns.
Database Users (client.databases.users)
Section titled “Database Users (client.databases.users)”Manage Postgres users inside a database.
list(databaseId: string): Promise<UserResponse[]>create(databaseId: string, req: CreateUserRequest): Promise<MessageResponse>delete(databaseId: string, username: string): Promise<MessageResponse>
await client.databases.users.create(databaseId, { username: 'app_user', password: 'AppUserPass!'});
const users = await client.databases.users.list(databaseId);users.forEach((u) => { console.log(u.name, u.can_login, u.can_create_db, u.is_superuser);});
await client.databases.users.delete(databaseId, 'app_user');Filesystem (client.fs)
Section titled “Filesystem (client.fs)”Cloud filesystem operations for reading, writing, and managing files attached to each database. Built for RAG pipelines, document ingestion, and agent workflows.
WebSocket requirement: Filesystem operations use WebSocket connections. Node.js 21+ and browsers have native WebSocket support. On Node.js 18–20, install the
wspackage or pass aWebSocketconstructor viaDb9ClientOptions.WebSocket.
connect(dbId): Promise<FsClient>— Open a persistent WebSocket connection (caller must callclose())list(dbId, path): Promise<FileInfo[]>— List directory contentsread(dbId, path): Promise<string>— Read file content as textreadBinary(dbId, path): Promise<Uint8Array>— Read file as binarywrite(dbId, path, content): Promise<void>— Write a fileappend(dbId, path, content): Promise<number>— Append to a file, returns bytes writtenstat(dbId, path): Promise<FileInfo>— Get file metadataexists(dbId, path): Promise<boolean>— Check if file existsmkdir(dbId, path): Promise<void>— Create a directory recursivelyremove(dbId, path, opts?): Promise<void>— Delete a file or directoryrename(dbId, oldPath, newPath): Promise<void>— Move or rename a path
import { createDb9Client } from 'get-db9';
const client = createDb9Client();const dbId = 'my-database-id';
// Create directory and write a fileawait client.fs.mkdir(dbId, '/data');await client.fs.write(dbId, '/data/hello.txt', 'Hello from db9!');
// Read file contentconst content = await client.fs.read(dbId, '/data/hello.txt');
// List directoryconst files = await client.fs.list(dbId, '/data/');for (const file of files) { console.log(file.path, file.type, file.size);}
// Stat and check existenceconst info = await client.fs.stat(dbId, '/data/hello.txt');console.log(info.type, info.size, info.mtime);
const exists = await client.fs.exists(dbId, '/data/hello.txt');console.log('File exists:', exists);
// Append and renameawait client.fs.append(dbId, '/data/hello.txt', '\nHello again');await client.fs.rename(dbId, '/data/hello.txt', '/data/hello-2.txt');
// Cleanupawait client.fs.remove(dbId, '/data/hello-2.txt');await client.fs.remove(dbId, '/data');FileInfo
Section titled “FileInfo”| Field | Type | Description |
|---|---|---|
path | string | Full file path. |
size | number | File size in bytes. |
type | 'file' | 'dir' | Entry type. |
mode | number | Unix file mode. |
mtime | string | Last modified time as RFC 3339 text. |
FsRemoveOptions
Section titled “FsRemoveOptions”| Option | Type | Description |
|---|---|---|
recursive | boolean | Remove directories recursively (default: false). |
Performance note: Convenience methods like
read(),write(), andlist()each open and close a WebSocket connection per call. For batch operations, useclient.fs.connect(dbId)to open a persistent connection.
Credential Storage
Section titled “Credential Storage”Credential stores implement a shared async interface used by client auto-auth.
FileCredentialStore(path?)— TOML file store at~/.db9/credentials(shared withdb9CLI)MemoryCredentialStore— Volatile in-memory store for tests and serverlessdefaultCredentialStore()— Factory that returnsnew FileCredentialStore()
import { createDb9Client, FileCredentialStore, MemoryCredentialStore, defaultCredentialStore} from 'get-db9';
const fileStore = new FileCredentialStore();const customStore = new FileCredentialStore('/tmp/db9-credentials.toml');const memStore = new MemoryCredentialStore();
const client = createDb9Client({ credentialStore: fileStore });Error Handling
Section titled “Error Handling”API failures throw named Db9Error subclasses based on HTTP status code.
Db9Error— Base class withstatusCode,message, and optionalresponseDb9AuthError— Status401Db9NotFoundError— Status404Db9ConflictError— Status409(e.g., duplicate database name)
import { createDb9Client, Db9Error, Db9AuthError, Db9NotFoundError, Db9ConflictError} from 'get-db9';
const client = createDb9Client();
try { await client.databases.get('missing-id');} catch (error) { if (error instanceof Db9NotFoundError) { console.error('Database not found'); } else if (error instanceof Db9AuthError) { console.error('Authentication required — run `db9 login` first'); } else if (error instanceof Db9ConflictError) { console.error('Conflict (e.g., duplicate name)'); } else if (error instanceof Db9Error) { console.error(`db9 API error ${error.statusCode}: ${error.message}`); } else { throw error; }}TypeScript Types Reference
Section titled “TypeScript Types Reference”The package re-exports all interfaces from ./types in addition to client, credential, and filesystem types.
Common
Section titled “Common”MessageResponse, ColumnInfo, SqlResult, SqlErrorDetail, TenantState
Customer Requests
Section titled “Customer Requests”CreateDatabaseRequest, SqlExecuteRequest, DumpRequest, MigrationApplyRequest, BranchRequest, CreateUserRequest, CreateTokenRequest
Customer Responses
Section titled “Customer Responses”CustomerResponse, DatabaseResponse, CustomerPasswordResetResponse, CreateConnectTokenResponse, TokenResponse, CreateTokenResponse, DumpResponse, SchemaResponse, TableMetadata, ColumnMetadata, ViewMetadata, MigrationApplyResponse, MigrationMetadata, UserResponse, TenantObservabilityResponse, ObservabilitySummary, QuerySample
Filesystem
Section titled “Filesystem”FileInfo, FsListOptions, FsRemoveOptions, FsConnectOptions, FsAuthInfo, FsWsRequest, FsWsResponse, FsWsError, StreamWriteReady
Credential and HTTP
Section titled “Credential and HTTP”Credentials, CredentialStore, FetchFn, HttpClient, HttpClientOptions, InstantDatabaseOptions, InstantDatabaseResult, Db9ClientOptions, Db9Client
Related Docs
Section titled “Related Docs”- CLI Reference — terminal-based database management
- Connect — connection strings, TLS, and driver configuration
- Provisioning — programmatic fleet management patterns
- Agent Workflows — SDK usage in agent pipelines
- Extensions — fs9, HTTP, vector, pg_cron, and more