Use the POST /api/v3/query endpoint of the Data 360 Query API to execute a SQL query against your Data 360 data. Submit a query in ASYNC mode to receive a queryId for polling, or use ADAPTIVE mode to receive results immediately when the query completes quickly. Both modes support JSON and Apache Arrow response formats.
important: This API is the recommended interface for new integrations. See Migrate from Query API V1 and V2 for guidance on updating existing code.
Syntax
- HTTP Method: POST
- Format: REST
- URI:
/api/v3/query
Request Headers
| Header | Value |
|---|---|
Authorization |
Bearer {accessToken} |
Content-Type |
application/json |
Accept |
application/json (default) or application/vnd.apache.arrow.stream |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
sql |
string | Yes | SQL query to execute. Uses Data 360 SQL syntax. |
transferMode |
string | No | Execution mode. Accepted values: ASYNC, ADAPTIVE (default). |
paramStyle |
string | No | Parameter binding style. Accepted values: QUESTION_MARK (default), NAMED, DOLLAR_NUMBERED. See Parameterized Queries. |
parameters |
array | No | Array of parameter objects for parameterized queries. Each object requires type (a Data 360 SQL type name) and value (a JSON string). See Parameterized Queries. |
settings |
object | No | See Query Settings for supported keys. |
resultRange |
object | No | Controls what is returned within the REST response. ADAPTIVE mode only. Supported keys: rowLimit (integer), byteLimit (integer, default and maximum 20 MB). |
queryRowLimit |
integer | No | Maximum number of rows to produce by the query. Acts as an implicit LIMIT clause. The query won't produce more rows than this value. Set to 0 to retrieve only the schema without producing any rows. |
Query Settings
The settings object accepts the following keys:
timezone— Time zone identifier for date and time values, for example"Etc/UTC".language— Language identifier for locale-specific formatting, for example"de_DE".date_style— Order of year, month, and day for parsing date strings. Accepted values:MDY,DMY,YMD. See Date/Time Input.lc_time— Locale for date literals, as an ISO language and country code, for example"en_US"or"de_AT".query_timeout— Execution limit in milliseconds before the query is terminated, for example1800000(30 minutes).
Parameterized Queries
The paramStyle request field controls how parameters are bound in your SQL:
QUESTION_MARK(default) — Use?placeholdersNAMED— Use named placeholders (:paramName)DOLLAR_NUMBERED— Use positional placeholders ($1,$2, ...)
Each object in the parameters array requires a type and a value.
type— A Data 360 SQL type name, such asvarchar,bigint, orboolean. For types that take a length or precision, include the relevant field, for example{ "type": "varchar", "length": 10, "value": "abc" }.value— The parameter value, always passed as a JSON string. Even for numeric types, pass the value as a string, for example"42", not42.
note: type takes SQL type names, not JSON type names. Use varchar rather than string.
Response Structure
Both ASYNC and ADAPTIVE modes share a common response structure.
Response Headers
Both ASYNC and ADAPTIVE modes return these response headers.
| Header | Description |
|---|---|
Date |
Timestamp when the response was generated. |
Content-Type |
application/json or application/vnd.apache.arrow.stream depending on the Accept request header. |
x-hyperdb-status |
JSON-serialized string containing the full query status. Fields: queryId, completionStatus, chunkCount, rowCount, progress, expirationTime, and executionStats. Use the queryId from this header to poll for results. |
Response Body — ASYNC Mode
In ASYNC mode, the response body omits the data field and returnedRows is 0. Use the queryId from the x-hyperdb-status response header to poll GET /api/v3/query/{queryId} for completion.
| Field | Description |
|---|---|
metadata |
Object containing column schema |
data |
Omitted in ASYNC mode |
returnedRows |
Always 0 in ASYNC mode |
Response Body — ADAPTIVE Mode
If the query completes within the adaptive timeout, data contains the result rows. If the query exceeds the adaptive timeout without producing rows, the response mimics ASYNC mode: the data field is omitted and returnedRows is 0. Use the queryId from the x-hyperdb-status response header to poll GET /api/v3/query/{queryId} for completion.
| Field | Description |
|---|---|
metadata |
Object containing column schema |
data |
Array of result rows (each row is an array); omitted if adaptive timeout reached |
returnedRows |
Number of rows returned (0 if adaptive timeout reached) |
Examples
These examples show ASYNC and ADAPTIVE requests and responses.
ASYNC Request
POST https://{dne_cdpInstanceUrl}/api/v3/query
Authorization: Bearer {accessToken}
Content-Type: application/json
{
"sql": "SELECT ssot__FirstName__c, ssot__LastName__c FROM ssot__Individual__dlm LIMIT 10",
"transferMode": "ASYNC"
}
ASYNC Response
Response headers (excerpt):
x-hyperdb-status: {"queryId":"MTAuMjcuMTgxLjE0OTo3NDg0_1cfc8d35-464c-9185-1f41-3eb638a71f7a","completionStatus":"RUNNING","chunkCount":0,"rowCount":0,"progress":0.0,"expirationTime":"2025-09-26T10:55:07.438Z","executionStats":{"wallClockTime":0.0,"rowsProcessed":0}}
Response body:
{
"metadata": {
"columns": [
{
"name": "ssot__FirstName__c",
"type": "varchar",
"nullable": true
},
{ "name": "ssot__LastName__c", "type": "varchar", "nullable": true }
]
},
"returnedRows": 0
}
ADAPTIVE Request
POST https://{dne_cdpInstanceUrl}/api/v3/query
Authorization: Bearer {accessToken}
Content-Type: application/json
{
"sql": "SELECT ssot__FirstName__c, ssot__LastName__c FROM ssot__Individual__dlm LIMIT 10",
"transferMode": "ADAPTIVE"
}
ADAPTIVE Response
{
"metadata": {
"columns": [
{
"name": "ssot__FirstName__c",
"type": "varchar",
"nullable": true
},
{ "name": "ssot__LastName__c", "type": "varchar", "nullable": true }
]
},
"data": [
["Alice", "Johnson"],
["Bob", "Smith"]
],
"returnedRows": 2
}
Parameterized Request
This ADAPTIVE request binds two parameters. The paramStyle is QUESTION_MARK, so each ? placeholder is filled from the parameters array in order.
POST https://{dne_cdpInstanceUrl}/api/v3/query
Authorization: Bearer {accessToken}
Content-Type: application/json
{
"sql": "SELECT ssot__FirstName__c, ssot__LastName__c FROM ssot__Individual__dlm WHERE ssot__CountryCode__c = ? AND ssot__Age__c >= ? LIMIT 10",
"transferMode": "ADAPTIVE",
"paramStyle": "QUESTION_MARK",
"parameters": [
{ "type": "varchar", "value": "US" },
{ "type": "bigint", "value": "18" }
]
}
ADAPTIVE Request with Query Settings
This ADAPTIVE request sets date_style, lc_time, and query_timeout to control date parsing, locale, and the execution timeout. Without an explicit date_style, the 01/08/1999 literal is ambiguous.
POST https://{dne_cdpInstanceUrl}/api/v3/query
Authorization: Bearer {accessToken}
Content-Type: application/json
{
"sql": "SELECT ssot__FirstName__c, ssot__LastName__c FROM ssot__Individual__dlm WHERE ssot__BirthDate__c > '01/08/1999' LIMIT 10",
"transferMode": "ADAPTIVE",
"settings": {
"date_style": "MDY",
"lc_time": "en_US",
"query_timeout": "1800000"
}
}
Apache Arrow Responses
Set Accept: application/vnd.apache.arrow.stream to request a binary Arrow IPC stream instead of JSON. Use an Arrow-compatible client library (such as PyArrow or the Apache Arrow Java library) to read the stream.
ASYNC Mode (Apache Arrow)
In ASYNC mode, the response body always contains only schema metadata with no data rows, regardless of the Accept header. Retrieve the queryId from the x-hyperdb-status response header and poll GET /api/v3/query/{queryId} for completion, then use GET /api/v3/query/{queryId}/rows or /chunks/{chunkId} with Accept: application/vnd.apache.arrow.stream to retrieve results.
ADAPTIVE Mode (Apache Arrow)
Set Accept: application/vnd.apache.arrow.stream to receive an inline ADAPTIVE result as a binary Arrow IPC stream. If the query exceeds the adaptive timeout and falls back to ASYNC mode, the response body contains only schema metadata with no data rows. Retrieve the queryId from the x-hyperdb-status response header and poll GET /api/v3/query/{queryId} for completion.
Error Handling
V3 returns structured error objects with HTTP status codes.
| Status | Meaning |
|---|---|
| 400 | Invalid SQL or request payload |
| 401 | Missing or invalid authentication |
| 408 | Request timed out |
| 429 | Rate limit exceeded |
| 500 | Internal server error |
Error responses include a rich error model with SQLSTATE codes and human-readable detail.
{
"error": "42601",
"message": "syntax error [TraceId:03d7d84a302b827ea8f0fe1d251f4eaf]",
"details": {
"customerDetail": "line 1, column 49: ...",
"errorSource": "User",
"position": {
"errorBeginCharacterOffset": "48",
"errorEndCharacterOffset": "53"
}
}
}
The position field is included for syntax errors. errorSource indicates whether the error originated from user input ("User") or the system. See Query Services Status Codes for the full reference.
Related Resources
- Query Data using Query API — Connect REST API (recommended for most integrations)
- Query V1 and V2 API — Legacy API reference
- Query Services Status Codes — Error code reference
- API Limits and Guidelines