> ## Documentation Index
> Fetch the complete documentation index at: https://docs.e6data.com/llms.txt
> Use this file to discover all available pages before exploring further.

# REST API for SQL queries

> Run SQL on e6data over the language-agnostic HTTP REST v2 API - authenticate, submit a statement, poll, and page through results.

The HTTP REST v2 API is a language-agnostic, firewall-friendly way to run SQL on e6data over HTTPS. It's a two-step flow: authenticate once for a short-lived session token, then submit statements and read results. Submission is asynchronous - you get a `statement_id`, poll for completion, then fetch result chunks.

<Info>
  The endpoint requires **HTTP/2**. Use an HTTP/2-capable client and don't force curl's `--http2` flag - ALPN negotiates HTTP/2 automatically.
</Info>

## Authenticate

Exchange your email and a [personal access token](/platform/tokens/pat-and-service-account-keys) for a session token. Tokens are opaque strings starting with `e6pat_` (PATs) or `e6sa_` (service account keys) - treat them like passwords.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
SESSION=$(curl -s -X POST \
  -H "Content-Type: application/json" \
  -H "cluster-name: <CLUSTER>" \
  -d '{"user":"<EMAIL>","password":"e6pat_..."}' \
  "https://<HOST>/api/v1/authenticate" | jq -r '.sessionId')
```

You can also send a token directly as `Authorization: Bearer <token>`, or use an SSO/OIDC JWT as a bearer token.

## Submit a statement

Required headers: `cluster-name: <CLUSTER>`, `Content-Type: application/json`, and `Authorization: Bearer <session>`.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -s -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $SESSION" \
  -H "cluster-name: <CLUSTER>" \
  -d '{"statement":"SELECT * FROM sales LIMIT 1000",
       "catalog":"<CATALOG>","schema":"<SCHEMA>",
       "wait_timeout":"30s","format":"JSON_ARRAY"}' \
  "https://<HOST>/api/v2/sql/statements"
# -> {"statement_id":"stmt-…","status":{"state":"RUNNING"},"session_id":"eyJ…"}
```

## Poll and fetch results

Reuse `session_id` via the `X-Session-Id` header to skip re-authentication while polling and paging:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -s "https://<HOST>/api/v2/sql/statements/<stmt-id>" \
  -H "cluster-name: <CLUSTER>" -H "X-Session-Id: <session_id>"

curl -s "https://<HOST>/api/v2/sql/statements/<stmt-id>/result/chunks/0" \
  -H "cluster-name: <CLUSTER>" -H "X-Session-Id: <session_id>"
```

## Endpoints

| Endpoint | Purpose |
| - | - |
| `POST /api/v1/authenticate` | Exchange credentials for a session token |
| `POST /api/v2/sql/statements` | Submit a statement |
| `GET /api/v2/sql/statements/{id}` | Poll status / get the first result chunk |
| `GET /api/v2/sql/statements/{id}/result/chunks/{n}` | Page through large results |
| `POST /api/v2/sql/statements/{id}/cancel` | Cancel a running statement |
| `POST /api/v2/sql/statements/{id}/clearOrCancel` | Free planner resources when you're done |
| `GET /api/v2/sql/statements/{id}/explain-analyze` | Query plan and timings |

Statement states: `PENDING → RUNNING → SUCCEEDED` (or `FAILED` / `CANCELLED`).

## Python example

Use `httpx` (not `requests`) since the endpoint requires HTTP/2 - `pip install "httpx[http2]"`:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import httpx

HOST = "https://<HOST>"
CLUSTER = "<CLUSTER>"

with httpx.Client(http2=True) as client:
    session = client.post(
        f"{HOST}/api/v1/authenticate",
        headers={"cluster-name": CLUSTER},
        json={"user": "<EMAIL>", "password": "e6pat_..."},
    ).json()["sessionId"]

    stmt = client.post(
        f"{HOST}/api/v2/sql/statements",
        headers={"cluster-name": CLUSTER, "Authorization": f"Bearer {session}"},
        json={"statement": "SELECT 1+1 AS result", "catalog": "<CATALOG>", "schema": "<SCHEMA>"},
    ).json()
    print(stmt)
```

## Operational notes

* **Reuse sessions** via `X-Session-Id` while polling and paging to avoid re-authenticating.
* **Page large results** with `result/chunks/{n}`, and call `clearOrCancel` when finished to free cluster resources promptly.
* **Suspended clusters** auto-resume on the first statement; the request waits (\~30–90 s).
* Use `POST /api/v2/sql/statements` (v2) - not the older `/api/v1/query` path.

## See also

* [Connecting to the engine](/query/connect) - all protocols and the connection-string cheat sheet.
* [PostgreSQL protocol](/query/connect/postgresql-protocol)
* [Access tokens](/platform/tokens/pat-and-service-account-keys)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.