Complete reference for the Absolute DB REST API, gRPC services, WebSocket live queries, GraphQL, and MCP server endpoints.
Absolute DB listens on multiple ports simultaneously. All REST and GraphQL traffic is served on port 8080; the PostgreSQL wire protocol on 5433 (or 5432 with -p 5432).
| Protocol | Default Port | Base URL |
|---|---|---|
| REST + Web Console | 8080 | http://host:8080/api/v1/ |
| GraphQL | 8080 | http://host:8080/graphql |
| WebSocket | 8080 | ws://host:8080/ws |
| CDC WebSocket | 8080 | ws://host:8080/cdc |
| MCP Server | 8080 | http://host:8080/mcp |
| OpenAPI spec | 8080 | http://host:8080/openapi.json |
| PostgreSQL Wire v3 | 5433 | Connection string — see Developer Guide |
| gRPC / HTTP/2 | 9090 | grpc://host:9090 |
| Redis RESP3 | 6379 | redis://host:6379 |
| Prometheus metrics | 8080 | http://host:8080/metrics |
All REST endpoints require an Authorization header. Both JWT bearer tokens and HTTP Basic auth are supported.
Authorization: Bearer <jwt-token>
Authorization: Basic <base64(user:password)>
X-AbsDB-Database: mydb # optional: select database
X-AbsDB-Schema: public # optional: set search_path
Content-Type: application/json
curl -X POST http://localhost:8080/api/v1/auth/token \
-H 'Content-Type: application/json' \
-d '{"username":"admin","password":"secret"}'
# Response
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_in": 86400,
"token_type": "Bearer"
}
The REST API provides HTTP access to all database operations. All request and response bodies are JSON unless otherwise noted. An auto-generated OpenAPI spec is available at /openapi.json.
{"healthy":true,"version":"","status":"running"} ) — used by load balancers and K8s liveness probesExecute a SQL SELECT statement and receive results as a JSON object containing column metadata and row data. Parameterised queries are supported with $1, $2 placeholders.
{
"sql": "SELECT id, name, score FROM users WHERE active = true ORDER BY score DESC LIMIT 10",
"params": [],
"database": "mydb",
"timeout_ms": 5000
}
{
"columns": [
{"name": "id", "type": "INTEGER", "nullable": false},
{"name": "name", "type": "TEXT", "nullable": false},
{"name": "score", "type": "REAL", "nullable": true}
],
"rows": [
[42, "Alice", 99.5],
[17, "Bob", 88.0]
],
"row_count": 2,
"execution_time_us": 140,
"plan_cache_hit": true
}
{
"sql": "SELECT * FROM orders WHERE customer_id = $1 AND status = $2",
"params": [42, "pending"]
}
| Field | Type | Required | Description |
|---|---|---|---|
sql | string | Yes | SQL SELECT statement |
params | array | No | Bind parameters ($1, $2, …) |
database | string | No | Target database name |
timeout_ms | integer | No | Query timeout in milliseconds (default 30000) |
Execute any SQL statement that modifies data or schema: INSERT, UPDATE, DELETE, CREATE TABLE, DROP, ALTER, etc. Supports RETURNING clause.
{
"sql": "INSERT INTO events (type, payload, ts) VALUES ($1, $2, NOW()) RETURNING id, ts",
"params": ["login", "{\"user\": \"alice\"}"]
}
{
"rows_affected": 1,
"last_insert_id": 1024,
"returning": [
{"id": 1024, "ts": "2026-04-06T09:15:00Z"}
],
"execution_time_us": 220
}
Bulk-insert rows from a JSON array. This path bypasses the SQL parser for maximum throughput — targeting the direct API rate of 704K–736K rows/sec.
{
"table": "metrics",
"columns": ["ts", "host", "value"],
"rows": [
["2026-04-06T09:00:00Z", "web-01", 12.5],
["2026-04-06T09:00:01Z", "web-02", 14.1],
["2026-04-06T09:00:02Z", "web-01", 13.8]
],
"on_conflict": "ignore"
}
{
"rows_inserted": 3,
"rows_skipped": 0,
"execution_time_us": 18
}
The on_conflict field accepts "ignore", "replace", or "error" (default).
Simple table scan via query parameters. Useful for quick integrations without constructing a full SQL query.
GET /api/v1/read?table=users&limit=20&offset=0&order_by=created_at&order=desc
GET /api/v1/read?table=products&where=category%3D'electronics'&limit=50
| Parameter | Type | Description |
|---|---|---|
table | string | Table name (required) |
columns | string | Comma-separated column list (default: *) |
where | string | URL-encoded WHERE clause predicate |
limit | integer | Max rows to return (default 100, max 10000) |
offset | integer | Row offset for pagination |
order_by | string | Column to sort by |
order | string | asc or desc |
Returns Prometheus text-format metrics. Also available at /metrics for direct Prometheus scrape configuration. OpenTelemetry OTLP export is also supported.
# HELP absdb_queries_total Total SQL queries executed
# TYPE absdb_queries_total counter
absdb_queries_total{type="select"} 1482903
absdb_queries_total{type="insert"} 294871
absdb_queries_total{type="update"} 18204
# HELP absdb_query_latency_us Query latency in microseconds
# TYPE absdb_query_latency_us histogram
absdb_query_latency_us_bucket{le="1"} 12094
absdb_query_latency_us_bucket{le="10"} 1289043
absdb_query_latency_us_bucket{le="100"} 1481200
absdb_query_latency_us_bucket{le="+Inf"} 1482903
# HELP absdb_buffer_pool_hit_rate LIRS buffer pool hit rate
# TYPE absdb_buffer_pool_hit_rate gauge
absdb_buffer_pool_hit_rate 0.987
# HELP absdb_active_connections Current open connections
# TYPE absdb_active_connections gauge
absdb_active_connections{protocol="pg_wire"} 14
absdb_active_connections{protocol="rest"} 3
absdb_active_connections{protocol="grpc"} 2
{
"version": "",
"codename": "",
"uptime_s": 86412,
"databases": 4,
"active_connections": 19,
"wal_lsn": "0/3A2F0080",
"buffer_pool_mb": 256,
"buffer_pool_hit_rate": 0.987
}
Full GraphQL API auto-generated from your database tables. Supports queries, mutations, subscriptions, and introspection. Compatible with Apollo Client, Relay, and any standards-compliant GraphQL client.
POST /graphql
Content-Type: application/json
{
"query": "query GetUsers($limit: Int) {
users(limit: $limit, order_by: {score: desc}) {
id
name
score
orders_aggregate { aggregate { count } }
}
}",
"variables": { "limit": 10 }
}
{
"query": "mutation InsertOrder($input: orders_insert_input!) {
insert_orders_one(object: $input) { id created_at }
}",
"variables": {
"input": {"customer_id": 42, "total": 149.99, "status": "pending"}
}
}
ws://host:8080/graphql
{"type":"subscribe","payload":{
"query":"subscription { orders(where:{status:{_eq:\"pending\"}}){ id total } }"
}}
Native HTTP/2 + Protobuf gRPC — no grpc-c dependency, implemented in pure C11. Supports full HPACK header compression, stream multiplexing, and flow control.
syntax = "proto3";
package absolutedb.v1;
service AbsoluteDB {
// Unary: execute single SQL statement
rpc Execute(ExecuteRequest) returns (ExecuteResponse);
// Server-streaming: large result sets
rpc Query(QueryRequest) returns (stream QueryRow);
// Bidirectional streaming: live change stream
rpc Subscribe(stream SubscribeRequest) returns (stream ChangeEvent);
}
message ExecuteRequest {
string sql = 1;
repeated bytes params = 2;
string database = 3;
}
message ExecuteResponse {
int64 rows_affected = 1;
int64 last_insert_id = 2;
int64 execution_time_us = 3;
}
message QueryRequest {
string sql = 1;
repeated bytes params = 2;
int32 batch_size = 3; // rows per stream message
}
# Plaintext
grpcurl -plaintext -d '{"sql":"SELECT COUNT(*) FROM users"}' \
localhost:9090 absolutedb.v1.AbsoluteDB/Execute
# With TLS
grpcurl -cacert ca.crt -d '{"sql":"SELECT version()"}' \
localhost:9090 absolutedb.v1.AbsoluteDB/Execute
Subscribe to live query change streams over WebSocket. Messages are JSON. Throughput: 29.2M+ notifications/sec via lock-free write rings.
// Client → Server: subscribe
{
"type": "subscribe",
"id": "sub-001",
"query": "SELECT id, status, total FROM orders WHERE status = 'pending'",
"mode": "diff" // "snapshot" | "diff" | "full"
}
// Server → Client: initial snapshot
{
"type": "snapshot",
"id": "sub-001",
"rows": [{"id": 1, "status": "pending", "total": 49.99}]
}
// Server → Client: incremental change
{
"type": "change",
"id": "sub-001",
"op": "INSERT",
"row": {"id": 2, "status": "pending", "total": 99.00}
}
// Client → Server: unsubscribe
{"type": "unsubscribe", "id": "sub-001"}
// Subscribe to WAL changes
{
"type": "subscribe_cdc",
"table": "orders",
"lsn_start": "0/3A200000",
"format": "debezium"
}
// Change event
{
"op": "u",
"before": {"id": 5, "status": "pending"},
"after": {"id": 5, "status": "shipped"},
"ts_ms": 1743933600000,
"lsn": "0/3A201800"
}
Native Model Context Protocol (MCP 2024-11-05) server. Exposes 5 built-in AI tools via JSON-RPC 2.0 over HTTP POST. Zero external dependencies — implemented in [internal component].
POST /mcp
{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}
// Response
{"jsonrpc":"2.0","id":1,"result":{"tools":[
{"name":"vector_search", "description":"HNSW semantic vector similarity search"},
{"name":"graph_relate", "description":"Create or traverse graph edges"},
{"name":"fts_search", "description":"BM25 full-text search with highlighting"},
{"name":"sql_execute", "description":"Execute arbitrary SQL statements"},
{"name":"rag_query", "description":"Retrieval-Augmented Generation pipeline"}
]}}
{
"jsonrpc": "2.0", "id": 2,
"method": "tools/call",
"params": {
"name": "vector_search",
"arguments": {
"table": "documents",
"vector_column": "embedding",
"query_vector": [0.12, -0.34, 0.89],
"top_k": 5,
"distance": "cosine"
}
}
}
{
"jsonrpc": "2.0", "id": 3,
"method": "tools/call",
"params": {
"name": "rag_query",
"arguments": {
"query": "What are the cancellation terms?",
"collection": "contracts",
"top_k": 3,
"rerank": true
}
}
}
All error responses use HTTP status codes and include a structured JSON body with an error object.
{
"error": {
"code": "SYNTAX_ERROR",
"message": "Unexpected token 'FORM' at position 14; did you mean 'FROM'?",
"sql_state": "42601",
"hint": "Check SQL syntax near position 14"
}
}
| HTTP | Error Code | Description |
|---|---|---|
| 400 | SYNTAX_ERROR | SQL parse error |
| 400 | INVALID_PARAM | Bad request body or parameter |
| 401 | UNAUTHORIZED | Missing or invalid auth token |
| 403 | PERMISSION_DENIED | Insufficient role privileges |
| 404 | TABLE_NOT_FOUND | Referenced table does not exist |
| 409 | UNIQUE_VIOLATION | Duplicate key constraint |
| 409 | FK_VIOLATION | Foreign key constraint failed |
| 429 | RATE_LIMITED | Too many requests |
| 500 | INTERNAL_ERROR | Unexpected server error |
| 503 | OVERLOADED | Server at capacity, retry with backoff |
| Tier | Requests/sec | Connections | Max Timeout |
|---|---|---|---|
| Community | 100 | 10 | 30 s |
| SME | 5,000 | 500 | 300 s |
| Professional | Unlimited | Unlimited | 3,600 s |
| Enterprise | Unlimited | 16 M virtual | Unlimited |
Rate limit headers are returned on every response: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.
~154 KB binary · zero external dependencies · 2,737 tests passing · SQL:2023 100%