Skip to content

HeliosDB Nano API Reference

Complete API reference for all HeliosDB Nano integration points across languages and deployment modes.


REST API (Server Mode)

Base URL: http://localhost:8080 (default)

Endpoints

Queries

Execute SQL Query

POST /v1/branches/{branch}/query
Content-Type: application/json
Request Body:
{
"sql": "SELECT * FROM users WHERE id = $1",
"params": [1]
}
Response (200 OK):
{
"rows": [
{"id": 1, "name": "Alice", "email": "alice@example.com"}
],
"columns": ["id", "name", "email"],
"rows_affected": 0
}
Error Response (400):
{
"error": {
"code": "42P01",
"message": "relation \"users\" does not exist"
}
}

Natural Language Query (planned)

A natural-language query (NL-to-SQL) route over HTTP is planned (roadmap); the current release does not route /v1/nl/query.

Query at Timestamp (Time-Travel)

POST /v1/branches/{branch}/query
Content-Type: application/json
Request Body:
{
"sql": "SELECT * FROM users",
"params": [],
"as_of_timestamp": "2025-01-01T00:00:00Z"
}
Response (200 OK):
{
"rows": [...],
"columns": [...],
"rows_affected": 0
}

Text Vector Search (planned)

Searching a store by text, with the server embedding the query, is planned (roadmap). In the current release POST /v1/vectors/stores/{store}/search/text is mounted but returns a not-implemented error; embed the query in your application and search by vector.

Vector Search by Vector

POST /v1/vectors/stores/{store}/search
Content-Type: application/json
Request Body:
{
"vector": [0.1, 0.2, 0.3, ...],
"top_k": 10,
"min_score": 0.5
}
Response (200 OK):
{
"results": [
{
"id": "doc_123",
"score": 0.95,
"content": "...",
"metadata": {}
}
]
}

Store Text with Embedding (planned)

Storing texts with server-side embedding is planned (roadmap). In the current release POST /v1/vectors/stores/{store}/texts is mounted but returns a not-implemented error; compute embeddings in your application and store them as vectors, or keep text and embeddings in a table and search it with SQL.

Vector Store Management

List Vector Stores

GET /v1/vectors/stores
Response (200 OK):
{
"stores": [
{
"name": "documents",
"dimensions": 1536,
"metric": "cosine",
"count": 1000
}
]
}

Create Vector Store

POST /v1/vectors/stores
Content-Type: application/json
Request Body:
{
"name": "documents",
"dimensions": 1536,
"metric": "cosine"
}
Response (201 Created):
{
"name": "documents",
"dimensions": 1536,
"metric": "cosine",
"count": 0
}

Branching

List Branches

GET /v1/branches
Response (200 OK):
{
"branches": [
{
"name": "main",
"parent": null,
"created_at": "2025-01-01T00:00:00Z"
},
{
"name": "dev",
"parent": "main",
"created_at": "2025-01-10T12:30:00Z"
}
]
}

Create Branch

POST /v1/branches
Content-Type: application/json
Request Body:
{
"name": "feature-branch",
"from_branch": "main"
}
Response (201 Created):
{
"name": "feature-branch",
"parent": "main",
"created_at": "2025-01-15T10:00:00Z"
}

Merge Branches

POST /v1/branches/{source}/merge
Content-Type: application/json
Request Body:
{
"target": "main"
}
Response (200 OK):
{
"status": "merged",
"changes": 5
}

Agent Memory (planned)

An agent-memory REST API (sessions, messages, memory search and summaries) is planned for Nano. In the current release the /v1/agents/memory routes are mounted but do not store sessions or messages yet: creating a session or adding a message returns a not-implemented error, and listing returns an empty result. Today, keep messages and their embeddings in a table and query them over the PostgreSQL wire protocol (recent history with ORDER BY id DESC LIMIT n, related messages with ORDER BY embedding <=> $1::vector(n)).

Document Management (planned)

Document ingest, chunking and search over HTTP are planned for Nano. In the current release the /v1/documents routes are mounted but do not store documents yet. Store text and embeddings in tables and search them with SQL (vector distance operators and ts_rank_cd).

Schema Inference

Infer a table from JSON samples

POST /v1/schema/infer takes sample JSON objects and returns inferred columns and a CREATE TABLE statement. Inference from CSV text and from files is planned (in the current release POST /v1/schema/infer/file returns a placeholder with a warning).

POST /v1/schema/infer
Content-Type: application/json
Request Body:
{
"samples": [
{"id": 1, "name": "Alice", "score": 95.5},
{"id": 2, "name": "Bob", "score": 87.3}
],
"table_name": "students"
}
Response (200 OK):
{
"success": true,
"data": {
"table_name": "students",
"columns": [
{"name": "id", "sql_type": "INTEGER", "nullable": false, ...},
...
],
"ddl": "CREATE TABLE students (...);",
"warnings": [...]
}
}

Review the generated ddl before running it: it marks every column NOT NULL and adds PRIMARY KEY (id).

Chat Completion (planned)

Chat completions over the Nano HTTP API are planned (roadmap). In the current release POST /v1/chat/completions is mounted but returns a not-implemented error; call your LLM provider from the application and pass it rows retrieved with SQL.

Query Management

Cancel Query

POST /v1/queries/{query_id}/cancel
Response (200 OK):
{
"status": "cancelled",
"query_id": "q_abc123"
}

List Running Queries

GET /v1/queries/?include_completed=false&user=app&database=main&state=executing
Response (200 OK):
{
"queries": [ ... ],
"total": 1
}

All query parameters are optional. Related routes: GET /v1/queries/stats, GET /v1/queries/{query_id}, POST /v1/queries/cancel-session and POST /v1/queries/cancel-timed-out.

Tenant Management (planned)

Tenant routes over HTTP are planned; the current release routes no /v1/tenants endpoints. Manage tenants, plans and quotas with the REPL \tenant commands or the embedded Rust API (see Multi-Tenancy).

In the stock Nano server, row-level security is enforced through the embedded API and the REPL; SQL CREATE POLICY and enforcement for REST and wire clients are planned.

Health

Health Check

GET /health
Response (200 OK):
{
"status": "ok"
}

GET /version returns the server version.


PostgreSQL Wire Protocol (Server Mode)

Standard PostgreSQL protocol on port 5432.

Connection String Format

postgresql://[user[:password]@][host][:port]/[database]
Examples:
postgresql://localhost:5432/mydb
postgresql://user:password@db.example.com:5432/mydb
postgres://localhost/mydb

Supported Features

  • Standard SQL (DML/DDL)
  • Parameterized queries ($1, $2,…)
  • Transactions (BEGIN/COMMIT/ROLLBACK)
  • Multiple data types
  • Indexes
  • Transactions with isolation levels

Supported Client Libraries

  • Python: psycopg2, asyncpg, sqlalchemy
  • JavaScript/Node: pg, node-postgres, sequelize
  • Rust: sqlx, tokio-postgres, diesel
  • Go: database/sql, pgx, sqlc
  • Java: JDBC, Hibernate
  • .NET: Npgsql, Entity Framework
  • PHP: PDO, php-pgsql

Rust API (Native/Embedded Mode)

Core Types

pub struct EmbeddedDatabase {
// ...
}
pub struct QueryResult {
pub rows: Vec<HashMap<String, Value>>,
pub columns: Vec<String>,
pub rows_affected: i64,
}
pub struct VectorSearchResult {
pub id: String,
pub score: f64,
pub content: Option<String>,
pub metadata: Option<HashMap<String, Value>>,
}
pub enum Value {
Null,
Bool(bool),
Int4(i32),
Int8(i64),
Float4(f32),
Float8(f64),
String(String),
Bytes(Vec<u8>),
Json(serde_json::Value),
Vector(Vec<f32>),
}

Core Methods

impl EmbeddedDatabase {
// Lifecycle
pub fn new(path: &str) -> Result<Self>;
pub fn new_in_memory() -> Result<Self>;
pub fn with_config(path: &str, config: Config) -> Result<Self>;
// Query execution
pub fn execute(&self, sql: &str, params: &[Value]) -> Result<()>;
pub fn query(&self, sql: &str, params: &[Value]) -> Result<QueryResult>;
pub fn query_row(&self, sql: &str, params: &[Value]) -> Result<Option<Row>>;
// Transactions
pub fn begin_transaction(&self) -> Result<Transaction>;
// Vector operations
pub fn vector_search(&self, store: &str, query: &str, top_k: usize)
-> Result<Vec<VectorSearchResult>>;
pub fn store_text(&self, store: &str, text: &str,
metadata: Option<HashMap<String, Value>>) -> Result<String>;
// Branching
pub fn create_branch(&self, name: &str, from: Option<&str>,
options: Option<BranchOptions>) -> Result<()>;
pub fn merge_branch(&self, source: &str, target: &str) -> Result<()>;
pub fn drop_branch(&self, name: &str) -> Result<()>;
pub fn switch_branch(&self, name: &str) -> Result<()>;
// Time-travel
pub fn query_as_of_timestamp(&self, sql: &str,
timestamp: &str, params: &[Value]) -> Result<QueryResult>;
pub fn query_as_of_transaction(&self, sql: &str,
txn_id: u64, params: &[Value]) -> Result<QueryResult>;
}

Trait Methods

pub trait ToSqlValue {
fn to_sql_value(&self) -> Value;
}
impl ToSqlValue for i32 { ... }
impl ToSqlValue for i64 { ... }
impl ToSqlValue for f64 { ... }
impl ToSqlValue for String { ... }
impl ToSqlValue for &str { ... }
impl ToSqlValue for bool { ... }
impl ToSqlValue for Vec<f32> { ... }

Python SDK API

Client

class Client:
def __init__(
self,
base_url: str = "http://localhost:8080",
api_key: Optional[str] = None,
branch: str = "main",
timeout: float = 30.0
) -> None: ...
async def query(
self,
sql: str,
params: Optional[List[Any]] = None,
branch: Optional[str] = None
) -> QueryResult: ...
async def execute(
self,
sql: str,
params: Optional[List[Any]] = None
) -> int: ...
async def nl_query(
self,
question: str
) -> Tuple[QueryResult, str]: ...
async def vector_search(
self,
store: str,
query: str,
top_k: int = 10,
min_score: Optional[float] = None,
filter: Optional[Dict[str, Any]] = None
) -> List[VectorSearchResult]: ...
async def store_text(
self,
store: str,
text: str,
metadata: Optional[Dict[str, Any]] = None
) -> str: ...
async def create_vector_store(
self,
name: str,
dimensions: int,
metric: str = "cosine"
) -> Dict[str, Any]: ...
async def list_vector_stores(self) -> List[Dict[str, Any]]: ...
async def create_branch(
self,
name: str,
from_branch: Optional[str] = None
) -> Dict[str, Any]: ...
async def merge_branch(self, source: str, target: str) -> None: ...
async def memory_add(
self,
session_id: str,
role: str,
content: str
) -> None: ...
async def memory_get(
self,
session_id: str,
limit: int = 50
) -> List[Dict[str, Any]]: ...
async def memory_search(
self,
session_id: str,
query: str,
top_k: int = 5
) -> List[VectorSearchResult]: ...
async def close(self) -> None: ...

Data Classes

@dataclass
class QueryResult:
rows: List[Dict[str, Any]]
columns: List[str]
rows_affected: int = 0
@dataclass
class VectorSearchResult:
id: str
score: float
content: Optional[str] = None
metadata: Optional[Dict[str, Any]] = None
@dataclass
class VectorStore:
name: str
dimensions: int
metric: str
count: int
@dataclass
class Branch:
name: str
parent: Optional[str] = None
created_at: str = ""
@dataclass
class Message:
role: str
content: str
timestamp: Optional[str] = None

TypeScript SDK API

Client

class HeliosDBClient {
constructor(config: ClientConfig);
async query(sql: string, params?: any[]): Promise<QueryResult>;
async execute(sql: string, params?: any[]): Promise<number>;
async nlQuery(question: string): Promise<[QueryResult, string]>;
async vectorSearch(
store: string,
query: string,
options?: VectorSearchOptions
): Promise<VectorSearchResult[]>;
async storeText(
store: string,
text: string,
metadata?: Record<string, any>
): Promise<string>;
async createVectorStore(
name: string,
dimensions: number,
metric?: string
): Promise<Record<string, any>>;
async listVectorStores(): Promise<Record<string, any>[]>;
async createBranch(
name: string,
fromBranch?: string
): Promise<Record<string, any>>;
async mergeBranch(source: string, target: string): Promise<void>;
async memoryAdd(
sessionId: string,
role: string,
content: string
): Promise<void>;
async memoryGet(
sessionId: string,
limit?: number
): Promise<Record<string, any>[]>;
async memorySearch(
sessionId: string,
query: string,
topK?: number
): Promise<VectorSearchResult[]>;
async close(): Promise<void>;
}

Types

interface QueryResult {
rows: Record<string, any>[];
columns: string[];
rows_affected?: number;
}
interface VectorSearchResult {
id: string;
score: number;
content?: string;
metadata?: Record<string, any>;
}
interface ClientConfig {
baseUrl?: string;
apiKey?: string;
branch?: string;
timeout?: number;
}
interface VectorSearchOptions {
topK?: number;
minScore?: number;
filter?: Record<string, any>;
}

Go SDK API

Client

type Client struct {
// ...
}
func NewClient(baseURL, apiKey string) *Client
func (c *Client) Query(ctx context.Context, sql string,
params ...interface{}) (*QueryResult, error)
func (c *Client) Execute(ctx context.Context, sql string,
params ...interface{}) (int64, error)
func (c *Client) NLQuery(ctx context.Context, question string)
(*QueryResult, string, error)
func (c *Client) VectorSearch(ctx context.Context, store, query string,
opts ...*SearchOptions) ([]VectorSearchResult, error)
func (c *Client) StoreText(ctx context.Context, store, text string,
metadata map[string]interface{}) (string, error)
func (c *Client) CreateBranch(ctx context.Context, name string,
fromBranch ...string) error
func (c *Client) MergeBranch(ctx context.Context, source, target string) error
func (c *Client) MemoryAdd(ctx context.Context, sessionID, role, content string)
error
func (c *Client) MemoryGet(ctx context.Context, sessionID string,
limit int) ([]map[string]interface{}, error)
func (c *Client) MemorySearch(ctx context.Context, sessionID, query string,
topK int) ([]VectorSearchResult, error)
func (c *Client) Close() error

Types

type QueryResult struct {
Rows []map[string]interface{}
Columns []string
RowsAffected int64
}
type VectorSearchResult struct {
ID string
Score float64
Content *string
Metadata map[string]interface{}
}
type SearchOptions struct {
TopK int
MinScore *float64
Filter map[string]interface{}
}

Error Codes & Responses

HTTP Response Codes

CodeMeaningExample
200SuccessQuery executed
201CreatedResource created
400Bad RequestInvalid SQL syntax
401UnauthorizedMissing or expired token on an /auth/v1 route
404Not FoundTable not found
429Rate LimitedToo many requests
500Server ErrorInternal error

PostgreSQL Error Codes (SQLSTATE)

CodeClassMeaning
00000SUCCESSSuccess
42P01SYNTAX_ERRORRelation does not exist
42P02SYNTAX_ERRORColumn does not exist
23505INTEGRITYUnique violation
23503INTEGRITYForeign key violation
25001TRANSACTIONTransaction failed

Configuration Reference

Server Configuration (heliosdb.toml)

[storage]
path = "./heliosdb-data"
cache_size = 536870912
compression = "Zstd"
memory_only = false
[server]
listen_addr = "127.0.0.1"
port = 5432
max_connections = 100
[performance]
simd_enabled = true
worker_threads = 0 # 0 = one per CPU core
[encryption]
enabled = false
algorithm = "Aes256Gcm"
[encryption.key_source]
Environment = "HELIOSDB_ENCRYPTION_KEY"
[vector]
# Product Quantization is chosen per index, not in this file:
# CREATE INDEX ... USING hnsw (embedding) WITH (quantization = 'product');

Command-Line Flags

Listener and data settings come from heliosdb-nano start flags or the config file, not from environment variables:

FlagDefaultMeaning
--data-dir <dir> (or -m/--memory)requiredData directory, or in-memory mode
--listen <addr>127.0.0.1PostgreSQL listener address
--port <port>5432PostgreSQL listener port
--http-port <port>8080HTTP API port (0 disables the HTTP listener)
--http-listen <addr>value of --listenHTTP API listener address
--config <file>noneTOML configuration file

Keep the HTTP and MySQL listeners on loopback (the default): API-key authentication for the HTTP API is planned, and a smaller listening surface is good practice anyway.

Environment Variables

VariableMeaning
HELIOSDB_ENCRYPTION_KEYEncryption-at-rest key (64 hex characters) when [encryption.key_source] Environment names it, as in the default
RUST_LOGLog filter, for example RUST_LOG=info (default: warnings only)

Rate Limits & Quotas

Rate Limiting (Server Mode)

  • Default: 1000 requests/second per IP
  • Configurable via max_connections
  • WebSocket connections: 100/second

Resource Limits

  • Max query size: No hard limit
  • Max result rows: Limited by memory
  • Max vector dimensions: 4096
  • Max text length: 2 GB per cell

Changelog & Versioning

Versioning Scheme

MAJOR.MINOR.PATCH[-PRERELEASE]

  • MAJOR: Breaking API changes
  • MINOR: New features (backward compatible)
  • PATCH: Bug fixes
  • PRERELEASE: alpha, beta, rc

Compatibility

  • SDK versions must match server major version
  • Patch versions are forward compatible
  • Minor versions are forward compatible

Support & Contact