> For the complete documentation index, see [llms.txt](https://docs.e6data.com/query-engine/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.e6data.com/query-engine/developers/connecting-to-the-engine/rest-api-for-sql.md).

# 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.

{% hint style="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.
{% endhint %}

## Authenticate

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

```bash
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
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
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
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-engine/developers/connecting-to-the-engine.md) - all protocols and the connection-string cheat sheet.
* [PostgreSQL protocol](/query-engine/developers/connecting-to-the-engine/postgresql-protocol.md)
* [Access tokens](/query-engine/guides/security/access-tokens.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.e6data.com/query-engine/developers/connecting-to-the-engine/rest-api-for-sql.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
