---
title: "HTTP/REST API Protocol"
---

# HTTP/REST API Protocol

HeliosDB Full includes an HTTP gateway that runs SQL over HTTP and returns JSON. It
runs inside the `heliosdb-full` server process and reads and writes the same tables as
the wire-protocol listeners.

## Overview

| Property | Value |
|----------|-------|
| **Transport** | Plain HTTP/1.1 |
| **Default port** | 8443 (`--http-port`, `HELIOSDB_HTTP_PORT`) |
| **Bind address** | `127.0.0.1` (`--bind-addr`; non-loopback needs `--allow-external`) |
| **Enabled** | Yes (`--no-http` turns it off) |
| **Authentication** | One API key, `HELIOSDB_API_KEY`, sent as `Authorization: Bearer <key>` or `X-API-Key: <key>` |
| **SQL endpoint** | `POST /api/v1/query` with `{"query": "..."}` |

Port 8443 is only the default number: the gateway does not terminate TLS. Put it
behind a TLS-terminating reverse proxy or load balancer for connections that leave
the host.

## Quick Start

### cURL

```bash
# Liveness (no key needed)
curl -s http://127.0.0.1:8443/health

# Run SQL
curl -s -X POST http://127.0.0.1:8443/api/v1/query \
  -H "Authorization: Bearer $HELIOSDB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "SELECT id, name FROM users LIMIT 10"}'
```

### Python (requests)

```python
import os, requests

r = requests.post("http://127.0.0.1:8443/api/v1/query",
                  headers={"Authorization": f"Bearer {os.environ['HELIOSDB_API_KEY']}"},
                  json={"query": "SELECT id, name FROM users WHERE active"},
                  timeout=30)
body = r.json()
if not body.get("success"):
    raise RuntimeError(body.get("error"))
for row in body["rows"]:
    print(row)
```

### JavaScript (fetch)

```javascript
const res = await fetch("http://127.0.0.1:8443/api/v1/query", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.HELIOSDB_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ query: "SELECT COUNT(*) AS n FROM orders" }),
});
const body = await res.json();
if (!body.success) throw new Error(body.error);
console.log(body.rows[0][0]);
```

A successful response has `success`, `columns` (name and type), `rows` (arrays of
values) and `row_count`. A SQL error returns HTTP 200 with `success: false` and an
`error` message, so always check `success`.

## Documentation

- **[HTTP/REST API reference](/docs/full/reference/api/http_rest_api/)**: every
  endpoint, response format, pinned sessions for transactions, AI routes and limits
- **[Configuration](/docs/full/reference/protocols/http-rest/configuration/)**: port,
  bind address, TLS, API key and limits
- **[Examples](/docs/full/reference/protocols/http-rest/examples/)**: client code
- **[Compatibility](/docs/full/reference/protocols/http-rest/compatibility/)**: what
  the gateway supports and what it does not
