---
title: "Execute SQL query"
method: POST
path: "/sql"
tags: ["Gateway"]
---

# Execute SQL query

`POST /sql`

Execute a single SQL query or a batch of queries against a PostgreSQL branch.

**Authentication:** send the branch's PostgreSQL connection string in the
`Connection-String` header. The control-plane API key (Bearer token) is
**not** accepted on the gateway host.

**Routing:** the target branch, region, and endpoint type are taken from the
hostname embedded in the connection string, which must match the request host.
See the `Connection-String` security scheme for the host format.

**Single query:** provide `query` (and optional `params`) at the top level.

**Batch:** provide `queries` as an array of query objects, or send the request body
as a JSON array. Batch queries execute within a single transaction.

## Headers

- `Array-Mode` 'true' | 'false'
- `Raw-Text-Output` 'true' | 'false'
- `Batch-Isolation-Level` 'ReadCommitted' | 'ReadUncommitted' | 'RepeatableRead' | 'Serializable'
- `Batch-Read-Only` 'true' | 'false'
- `Batch-Deferrable` 'true' | 'false'

## Request body

- SQLRequest — SQL query request. Provide either `query` for a single query or `queries` for a batch.
  - `query` string — SQL query to execute (single query mode).
  - `params` unknown[] — Positional parameters for the query (`$1`, `$2`, ...).
    - unknown
  - `queries` QueryItem[] — Array of queries for batch execution within a single transaction.
    - `query` string, required — SQL query to execute.
    - `params` unknown[] — Positional parameters for the query.
      - unknown
    - `arrayMode` boolean — Override array mode for this individual query.
  - `arrayMode` boolean — Override array mode for this query (single query mode only).

## Response `200`

Query executed successfully

- union
  - QueryResult — Result of a single SQL query execution.
    - `fields` FieldDefinition[], required — Column metadata for the result set.
      - `name` string, required — Column name.
      - `tableID` integer, required — OID of the source table (0 if not a table column).
      - `columnID` integer, required — Attribute number of the column within the table.
      - `dataTypeID` integer, required — OID of the column data type.
      - `dataTypeSize` integer, required — Data type size (negative for variable-length types).
      - `dataTypeModifier` integer, required — Type-specific modifier (e.g. precision/scale for numeric types).
      - `format` string, required — Data format (`text` or `binary`).
    - `command` string, required — PostgreSQL command tag (e.g. `SELECT`, `INSERT`, `UPDATE`, `DELETE`).
    - `rowCount` integer, nullable, required — Number of rows affected by the command.
    - `rows` unknown[], required — Result rows. Each row is an object (column-name keys) or an array (when array mode is enabled).
      - unknown
    - `rowAsArray` boolean, required — Whether rows are returned as arrays (`true`) or objects (`false`).
  - BatchResponse — Response for a batch query execution.
    - `results` QueryResult[], required — Results for each query in the batch, in order.
      - `fields` FieldDefinition[], required — Column metadata for the result set.
        - `name` string, required — Column name.
        - `tableID` integer, required — OID of the source table (0 if not a table column).
        - `columnID` integer, required — Attribute number of the column within the table.
        - `dataTypeID` integer, required — OID of the column data type.
        - `dataTypeSize` integer, required — Data type size (negative for variable-length types).
        - `dataTypeModifier` integer, required — Type-specific modifier (e.g. precision/scale for numeric types).
        - `format` string, required — Data format (`text` or `binary`).
      - `command` string, required — PostgreSQL command tag (e.g. `SELECT`, `INSERT`, `UPDATE`, `DELETE`).
      - `rowCount` integer, nullable, required — Number of rows affected by the command.
      - `rows` unknown[], required — Result rows. Each row is an object (column-name keys) or an array (when array mode is enabled).
        - unknown
      - `rowAsArray` boolean, required — Whether rows are returned as arrays (`true`) or objects (`false`).

## Other responses

- `400` — Invalid request, SQL error, or query execution timeout
- `401` — Missing or invalid connection string
- `403` — Client IP is not allowed by the branch IP filter
- `404` — Branch not found, it may have been deleted
- `409` — Branch is hibernated, reactivate it before running queries
- `413` — Request body is larger than 64MB
- `500` — Internal server error
- `504` — Timed out connecting to the database
- `507` — Response too large

---

[API](https://skmtc.net/xataio/apis/xata-api.md) · [All operations](https://skmtc.net/xataio/apis/xata-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/xataio/xata-api/revisions/bbeb83bf32d6/schema)
