Installation
Install the SDK with your package manager. Runtime requirement is Node.js 18+ (native fetch), with TypeScript 5+ for full type exports.
npm install get-db9
yarn add get-db9
pnpm add get-db9
bun add get-db9
| Requirement | Minimum | Notes |
|---|---|---|
| Node.js | 18.0.0+ | Uses native fetch and modern ESM/CJS output. |
| TypeScript | 5.0+ | Required for complete type export support. |
| Credentials | ~/.db9/credentials | Default token storage shared with db9 CLI. |
Quick Start
instantDatabase() automatically creates or reuses a database named default, with anonymous auth handled under the hood.
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);
Result shape returned from instantDatabase():
interface InstantDatabaseResult {
databaseId: string;
connectionString: string;
adminUser: string;
adminPassword: string;
state: string;
createdAt: string;
}
instantDatabase(options?)
High-level API that wraps createDb9Client(), checks for an existing database by name, creates one if missing, and optionally executes seed SQL.
function instantDatabase(
options?: InstantDatabaseOptions
): Promise<InstantDatabaseResult>;
| Option | Type | Description |
|---|---|---|
name | string | Database name. Default: 'default'. |
baseUrl | string | Override API endpoint. |
fetch | FetchFn | Custom fetch implementation. |
credentialStore | CredentialStore | Token load/save strategy. |
seed | string | SQL text executed via client.databases.sql(). |
seedFile | string | SQL file content executed via client.databases.sqlFile(). |
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?)
Low-level typed client exposing grouped APIs: auth, tokens, and databases. If no token is provided, it lazily loads from credential store and auto-registers anonymously when needed.
function createDb9Client(options?: Db9ClientOptions): Db9Client;
| Option | Type | Description |
|---|---|---|
baseUrl | string | Default: https://staging.db9.ai/api. |
token | string | Optional bearer token; skips anonymous auto-flow. |
fetch | FetchFn | Inject 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. |
- Create public client (no Authorization header).
- Lazy-load token from credential store on first protected call.
- If token missing, call
/customer/anonymous-register. - Persist
token,anonymous_id, andanonymous_secretin credential store. - Create auth client with
Authorization: Bearer <token>.
import { createDb9Client, MemoryCredentialStore } from 'get-db9';
const client = createDb9Client({
baseUrl: 'https://staging.db9.ai/api',
credentialStore: new MemoryCredentialStore()
});
Authentication (client.auth)
Seven auth methods support full account lifecycle including anonymous bootstrap and claim-to-registered conversion.
register(req: RegisterRequest): Promise<CustomerResponse>login(req: LoginRequest): Promise<LoginResponse>anonymousRegister(): Promise<AnonymousRegisterResponse>anonymousRefresh(req: AnonymousRefreshRequest): Promise<AnonymousRefreshResponse>me(): Promise<CustomerResponse>getAnonymousSecret(): Promise<AnonymousSecretResponse>ensureAnonymousSecret(): Promise<void>— Persists secret to credential store if missingclaim(req: ClaimRequest): Promise<ClaimResponse>
const customer = await client.auth.register({
email: 'dev@example.com',
password: 'S3curePass!'
});
const login = await client.auth.login({
email: 'dev@example.com',
password: 'S3curePass!'
});
const anon = await client.auth.anonymousRegister();
const refreshed = await client.auth.anonymousRefresh({
anonymous_id: anon.anonymous_id,
anonymous_secret: anon.anonymous_secret
});
const me = await client.auth.me();
const secret = await client.auth.getAnonymousSecret();
const claimed = await client.auth.claim({
email: 'owner@example.com',
password: 'N3wPass!'
});
Token Management (client.tokens)
Create, inspect, and revoke customer 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>
// Create a named API token
const newToken = await client.tokens.create({
name: 'ci-deploy',
expires_in_days: 90
});
console.log(newToken.token); // Use this for CI/CD
// List all tokens
const tokens = await client.tokens.list();
for (const token of tokens) {
console.log(token.id, token.name, token.created_at, token.expires_at);
}
// Revoke a token
await client.tokens.revoke(tokens[0].id);
Database Management (client.databases)
Core lifecycle APIs: create, enumerate, inspect, delete, reset admin password, and read observability snapshots.
create(req: CreateDatabaseRequest): Promise<DatabaseResponse>list(): Promise<DatabaseResponse[]>get(databaseId: string): Promise<DatabaseResponse>delete(databaseId: string): Promise<MessageResponse>resetPassword(databaseId: string): Promise<CustomerPasswordResetResponse>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 metrics = await client.databases.observability(db.id);
await client.databases.delete(db.id);
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 & 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
Apply SQL migrations with checksums and inspect migration history metadata.
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
Create database branches from an existing database using a new branch name.
branch(databaseId: string, req: BranchRequest): Promise<DatabaseResponse>
const featureDb = await client.databases.branch(databaseId, {
name: 'feature-auth'
});
console.log(featureDb.id, featureDb.name, featureDb.connection_string);
Database Users (client.databases.users)
Manage Postgres users inside a customer 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');
Authentication Flow
Default client behavior for first-time users and progression from anonymous to registered identity.
Anonymous start
|
| createDb9Client() without token
v
anonymousRegister() -> { token, anonymous_id, anonymous_secret }
|
| token persisted in CredentialStore
v
Use client.* APIs as anonymous customer
|
| client.auth.claim({ email, password })
v
Registered customer account (same identity now claimed)
- Anonymous token is auto-provisioned and cached.
anonymousRefresh()can rotate token usinganonymous_id+anonymous_secret.- All authenticated API calls auto-retry on 401 with a fresh token (transparent to caller).
ensureAnonymousSecret()persists the secret to credential store if missing.claim()upgrades anonymous identity to email/password credentials.
Credential Storage
Credential stores implement a shared async interface used by client auto-auth.
FileCredentialStore(path?)- TOML file store at~/.db9/credentials.MemoryCredentialStore- volatile in-memory store for tests/serverless.defaultCredentialStore()- 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 store = defaultCredentialStore();
const client = createDb9Client({ credentialStore: fileStore });
Error Handling
API failures throw Db9Error subclasses based on HTTP status code.
Db9Error- base class withstatusCode,message, and optionalresponse.Db9AuthError- status401.Db9NotFoundError- status404.Db9ConflictError- status409.
import {
Db9Error,
Db9AuthError,
Db9NotFoundError,
Db9ConflictError
} from 'get-db9';
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');
} else if (error instanceof Db9ConflictError) {
console.error('Conflict while processing request');
} else if (error instanceof Db9Error) {
console.error(`db9 API error ${error.statusCode}: ${error.message}`);
} else {
throw error;
}
}
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.
list(dbId, path, options?): Promise<Fs9FileEntry[]>— List directory contentsread(dbId, path): Promise<string>— Read file content as textwrite(dbId, path, content): Promise<void>— Write text content to a filestat(dbId, path): Promise<Fs9FileEntry>— Get file metadatamkdir(dbId, path): Promise<void>— Create a directory (recursive)remove(dbId, path): Promise<void>— Delete a file or directoryreadBinary(dbId, path): Promise<ArrayBuffer>— Read file as binaryexists(dbId, path): Promise<boolean>— Check if file existsevents(dbId, opts?): Promise<Fs9EventEntry[]>— Get filesystem event log
import { createDb9Client } from 'get-db9/client';
const client = createDb9Client();
const dbId = 'my-database-id';
// Create directory and write a file
await client.fs.mkdir(dbId, '/data');
await client.fs.write(dbId, '/data/hello.txt', 'Hello from db9!');
// Read file content
const content = await client.fs.read(dbId, '/data/hello.txt');
// List directory
const files = await client.fs.list(dbId, '/data/');
for (const file of files) {
console.log(file.path, file.file_type, file.size);
}
// Stat a file
const info = await client.fs.stat(dbId, '/data/hello.txt');
console.log(info.file_type, info.size, info.mtime);
// Check existence
const exists = await client.fs.exists(dbId, '/data/hello.txt');
console.log('File exists:', exists);
// Get events
const events = await client.fs.events(dbId, { limit: 10, path: '/data' });
for (const event of events) {
console.log(event.type, event.path, event.timestamp);
}
// Cleanup
await client.fs.remove(dbId, '/data/hello.txt');
await client.fs.remove(dbId, '/data');
| Field | Type | Description |
|---|---|---|
path | string | Full file path. |
size | number | File size in bytes. |
file_type | 'regular' | 'directory' | 'symlink' | Entry type. |
mode | number | Unix file mode. |
uid | number | Owner user ID. |
gid | number | Owner group ID. |
atime | number | Last access (Unix timestamp). |
mtime | number | Last modified (Unix timestamp). |
ctime | number | Status change (Unix timestamp). |
etag | string | Content hash for caching. |
| Option | Type | Description |
|---|---|---|
recursive | boolean | List entries recursively (default: false). |
TypeScript Types Reference (All Public Interfaces)
The package re-exports all interfaces from ./types in addition to InstantDatabaseOptions, InstantDatabaseResult, Db9ClientOptions, and credential/http types.
Common
Endpoint, MessageResponse, HealthResponse, ColumnInfo, SqlResult, SqlErrorDetail, TenantState
Customer Requests
RegisterRequest, LoginRequest, CreateDatabaseRequest, SqlExecuteRequest, DumpRequest, MigrationApplyRequest, BranchRequest, ClaimRequest, AnonymousRefreshRequest, CreateUserRequest, CreateTokenRequest
Customer Responses
CustomerResponse, LoginResponse, AnonymousRegisterResponse, AnonymousRefreshResponse, AnonymousSecretResponse, ClaimResponse, DatabaseResponse, CustomerPasswordResetResponse, TokenResponse, CreateTokenResponse, DumpResponse, SchemaResponse, TableMetadata, ColumnMetadata, ViewMetadata, MigrationApplyResponse, MigrationMetadata, UserResponse, TenantObservabilityResponse, ObservabilitySummary, QuerySample
Filesystem
Fs9FileEntry, Fs9ListOptions, Fs9EventEntry, Fs9EventOptions
Credential & HTTP
Credentials, CredentialStore, FetchFn, HttpClient, HttpClientOptions, InstantDatabaseOptions, InstantDatabaseResult, Db9ClientOptions, Db9Client, Endpoint
export function instantDatabase(options?: InstantDatabaseOptions): Promise<InstantDatabaseResult>;
export { createDb9Client } from './client';
export type { Db9ClientOptions, Db9Client } from './client';
export { Db9Error, Db9AuthError, Db9NotFoundError, Db9ConflictError } from './errors';
export { FileCredentialStore, MemoryCredentialStore, defaultCredentialStore } from './credentials';
export type * from './types';