Skip to content

HTTP API

ParticleDB exposes an HTTP API on port 8080 for REST queries, health checks, dashboard access, and Prometheus metrics. The HTTP API is ideal for lightweight integrations, monitoring, and environments where a PostgreSQL driver is not available.

http://localhost:8080

Configure with:

Terminal window
particledb start --http-addr 0.0.0.0:8080
Terminal window
curl http://localhost:8080/health
{
"status": "ok",
"version": "0.1.0",
"uptime_seconds": 3600
}

Use this endpoint for load balancer health probes and container orchestration (Kubernetes liveness/readiness).

Execute a SQL query and receive JSON results.

Request:

Terminal window
curl -X POST http://localhost:8080/query \
-H "Content-Type: application/json" \
-d '{"sql": "SELECT name, price FROM products WHERE price > 50 ORDER BY price DESC"}'

Response:

{
"columns": ["name", "price"],
"rows": [
["4K Monitor", 399.99],
["Mechanical Keyboard", 89.99]
],
"row_count": 2,
"elapsed_ms": 1.2
}
Terminal window
curl -X POST http://localhost:8080/query \
-H "Content-Type: application/json" \
-d '{
"sql": "SELECT name, price FROM products WHERE price > $1 AND price < $2",
"params": [50, 200]
}'
Terminal window
# Create a table
curl -X POST http://localhost:8080/query \
-H "Content-Type: application/json" \
-d '{
"sql": "CREATE TABLE events (id BIGINT PRIMARY KEY, name VARCHAR NOT NULL, ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP)"
}'
# Insert data
curl -X POST http://localhost:8080/query \
-H "Content-Type: application/json" \
-d '{
"sql": "INSERT INTO events (id, name) VALUES ($1, $2)",
"params": [1, "signup"]
}'

DML Response:

{
"rows_affected": 1,
"elapsed_ms": 0.3
}

Insert multiple rows in a single request:

Terminal window
curl -X POST http://localhost:8080/bulk \
-H "Content-Type: application/json" \
-d '{
"table": "products",
"columns": ["id", "name", "price"],
"rows": [
[10, "Headphones", 59.99],
[11, "Mouse Pad", 12.99],
[12, "USB Cable", 8.99]
]
}'

Response:

{
"rows_inserted": 3,
"elapsed_ms": 1.8
}

List all tables:

Terminal window
curl http://localhost:8080/tables
{
"tables": [
{"name": "products", "row_count": 4, "columns": 5},
{"name": "events", "row_count": 1000, "columns": 3}
]
}

Get details for a specific table:

Terminal window
curl http://localhost:8080/tables/products
{
"name": "products",
"row_count": 4,
"columns": [
{"name": "id", "type": "BIGINT", "primary_key": true, "nullable": false},
{"name": "name", "type": "VARCHAR", "primary_key": false, "nullable": false},
{"name": "price", "type": "DOUBLE PRECISION", "primary_key": false, "nullable": true},
{"name": "embedding", "type": "VECTOR(384)", "primary_key": false, "nullable": true},
{"name": "created_at", "type": "TIMESTAMP", "primary_key": false, "nullable": true}
]
}

Prometheus-compatible metrics:

Terminal window
curl http://localhost:8080/metrics
# HELP particledb_queries_total Total number of queries executed
# TYPE particledb_queries_total counter
particledb_queries_total{type="select"} 15234
particledb_queries_total{type="insert"} 8921
particledb_queries_total{type="update"} 1204
# HELP particledb_connections_active Current active connections
# TYPE particledb_connections_active gauge
particledb_connections_active 12
# HELP particledb_query_duration_seconds Query execution duration
# TYPE particledb_query_duration_seconds histogram
particledb_query_duration_seconds_bucket{le="0.001"} 12000
particledb_query_duration_seconds_bucket{le="0.01"} 14500
particledb_query_duration_seconds_bucket{le="0.1"} 15100

The KV endpoints provide a simple key-value interface for applications that need fast single-key operations without writing SQL.

Retrieve a key-value pair.

Terminal window
curl -X POST http://localhost:8080/v1/kv/get \
-H "Content-Type: application/json" \
-d '{"key": "user:1001", "table": "kv_store"}'
{
"key": "user:1001",
"value": "{\"name\": \"Alice\", \"plan\": \"pro\"}",
"found": true
}

Create or update a key-value pair.

Terminal window
curl -X POST http://localhost:8080/v1/kv/set \
-H "Content-Type: application/json" \
-d '{"key": "user:1001", "value": "{\"name\": \"Alice\", \"plan\": \"enterprise\"}", "table": "kv_store"}'
{
"ok": true
}

Delete a key-value pair.

Terminal window
curl -X POST http://localhost:8080/v1/kv/delete \
-H "Content-Type: application/json" \
-d '{"key": "user:1001", "table": "kv_store"}'
{
"ok": true,
"deleted": true
}

Return the server version and build information.

Terminal window
curl http://localhost:8080/v1/version
{
"version": "0.1.0",
"build": "ed89c33",
"rust_version": "1.78.0"
}

All paths accept OPTIONS requests and return a 204 No Content response with the appropriate CORS headers (Access-Control-Allow-Origin, Access-Control-Allow-Methods, Access-Control-Allow-Headers). This enables browser-based clients to issue preflight checks without custom server configuration.

All errors return a JSON body with an error field and an appropriate HTTP status code:

{
"error": "Table 'nonexistent' does not exist",
"code": "42P01"
}
HTTP StatusMeaning
200Query executed successfully
400SQL syntax error or invalid parameters
401Authentication required
404Table or endpoint not found
500Internal server error

When authentication is enabled on the server, include credentials in your requests:

Terminal window
# Bearer token
curl -X POST http://localhost:8080/query \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"sql": "SELECT 1"}'
# Basic auth
curl -X POST http://localhost:8080/query \
-u admin:secret \
-H "Content-Type: application/json" \
-d '{"sql": "SELECT 1"}'

The HTTP API includes CORS headers for browser-based access. Configure allowed origins in config.toml:

[network]
cors_origins = ["http://localhost:3000", "https://app.example.com"]

The HTTP API shares the server’s global connection limit (--max-connections). Each HTTP request uses a connection for the duration of the query and returns it immediately after.