AutessaDB Analytics API
Query analytics tables from your own code: describe what a table holds, run read-only SQL as a job, page through or download the result, and keep the table fed by loading files or appending rows.
Every request is a POST with a JSON body to https://api.autessa.com/clients/autessadb/analytics/<operation>, with the analytics table's ID in the resourceId query parameter and your API key in the Authorization header (no Bearer prefix). For a query that joins several tables, resourceId is the primary table, and the key needs READ on every table the query reads.
Permissions
| Permission | Operations |
|---|---|
| READ | describe, preview, estimate, query, job-status, job-results, job-download-url, cancel, jobs |
| WRITE | load-from-s3, append-rows |
Creating tables, changing columns, and editing the semantic layer are on the Analytics Poweruser API and in the builder.
Values in results
Rows are JSON objects keyed by column name. Values keep their exact meaning:
| Column type | JSON value |
|---|---|
STRING, BOOLEAN, INT, DOUBLE | String, boolean, or number |
LONG | Number, or a string when the value is too large to be exact in JSON |
DECIMAL | String, e.g. "1284410.50" |
DATE | "2026-10-01" |
TIMESTAMP, TIMESTAMPTZ | ISO-8601 UTC string, e.g. "2026-10-01T00:00:00Z" |
STRING_LIST | Array of strings |
JSON | The JSON value |
| empty | null |
Queries are jobs
Every query, load, and append runs as a job. Queries run asynchronously and typically take a few seconds; large scans take longer. Queries are written in ANSI SQL; date and approximate functions use the standard analytical names such as date_trunc('month', ts), approx_distinct(col), and format_datetime(ts, 'yyyy-MM').
A typical query:
- Run a query with
waitMsup to 20 seconds. If the job finishes in that time, it comes backSUCCEEDEDwith apreviewof the first 200 rows. - If the state is
QUEUEDorRUNNING, call Get job status withwaitMsuntil it finishes. - Page through Get job results, or get a download link for the whole result.
Results are kept for 7 days. A query can run for at most 15 minutes (less on some plans) before it ends as TIMED_OUT.
Uploading a file to load
Files for Load files are uploaded with the client intake endpoints at https://api.autessa.com/clients/autessadb-intake, which send the bytes straight to storage in parts:
POST /multipart-initiatewith{"fileName": "orders-2026-09.csv"}returnsuploadId,s3Key, ands3Uri.POST /multipart-part-urlswithuploadId,s3Key, andpartNumbersreturns apartUrlsmap.PUTeach part (at least 5 MB except the last) to its link and keep each response'sETagheader.POST /multipart-completewithuploadId,s3Key, andpartETags(part number to ETag) returns the finals3Uri.
The CLI does all of this for you with autessa autessadb analytics load --localFile.
Describe tables
/describeReturns everything needed to query one or more analytics tables: SQL name, description, grain, row count, partition columns, columns with types and descriptions, measures, joins, and verified queries. Columns the caller cannot see are omitted. Agents should call this before writing SQL.
Permission: READ on every table described
Request parameters
- Name
tableId- Type
- string
- Description
The analytics table. For multi-table queries, the primary table; on the client API it must match the
resourceIdquery parameter.
- Name
tableIds- Type
- array<string>
- Description
Additional tables to describe in the same call.
- Name
includeStats- Type
- boolean
- Description
Include per-column statistics (null count, distinct count, minimum, maximum, and top values). Default
false.
Response
- Name
tables- Type
- array<object>
- Description
One entry per table:
tableId,sqlName,name,description,grain,rowCount,dataBytes,lastLoadAt,partitionSpec,columns(name,type,nullable,description,synonyms,masked, andstatswhen requested),measures(name,sql,description),joins(sqlName,on,relationship), andverifiedQueries(id,question,sql).
- Name
semanticsVersion- Type
- integer
- Description
Version of the primary table's semantic layer, for Update the semantic layer.
- cURL
- JavaScript
- Python
curl -X POST 'https://api.autessa.com/clients/autessadb/analytics/describe?resourceId=V1StGXR8Z5' \
-H "Authorization: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tableId": "V1StGXR8Z5",
"includeStats": false
}'
const response = await fetch(
'https://api.autessa.com/clients/autessadb/analytics/describe?resourceId=V1StGXR8Z5',
{
method: 'POST',
headers: {
'Authorization': process.env.API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
tableId: 'V1StGXR8Z5',
includeStats: false
})
}
);
const data = await response.json();
import os
import requests
response = requests.post(
'https://api.autessa.com/clients/autessadb/analytics/describe?resourceId=V1StGXR8Z5',
headers={'Authorization': os.environ['API_KEY']},
json={
'tableId': 'V1StGXR8Z5',
'includeStats': False
}
)
data = response.json()
{
"tables": [
{
"tableId": "V1StGXR8Z5",
"sqlName": "order_lines",
"name": "Order Lines",
"description": "Every order line since 2019, loaded nightly from the ERP.",
"grain": "one row per order line",
"rowCount": 418220931,
"dataBytes": 21474836480,
"lastLoadAt": "2026-10-02T06:00:12Z",
"partitionSpec": [
{
"column": "order_date",
"transform": "MONTH"
}
],
"columns": [
{
"name": "order_id",
"type": "LONG",
"nullable": false,
"description": "ERP order number."
},
{
"name": "order_date",
"type": "DATE",
"nullable": false,
"description": "Date the order was placed."
},
{
"name": "region",
"type": "STRING",
"nullable": false,
"description": "Sales region.",
"synonyms": [
"territory"
]
},
{
"name": "net_amount",
"type": "DECIMAL(18,2)",
"nullable": false,
"description": "Line revenue after discounts, in USD.",
"synonyms": [
"net sales"
]
}
],
"measures": [
{
"name": "revenue",
"sql": "SUM(net_amount)",
"description": "Net revenue in USD."
}
],
"joins": [
{
"sqlName": "customers",
"on": "order_lines.customer_id = customers.id",
"relationship": "MANY_TO_ONE"
}
],
"verifiedQueries": [
{
"id": "vq_7d2a",
"question": "Monthly revenue by region this year",
"sql": "SELECT region, date_trunc('month', order_date) AS month, SUM(net_amount) AS revenue\nFROM order_lines\nWHERE order_date >= DATE '2026-01-01'\nGROUP BY 1, 2\nORDER BY 2, 1"
}
]
}
],
"semanticsVersion": 6
}
Preview rows
/previewReturns the first rows of a table without writing SQL. Previews run ahead of regular queries.
Permission: READ
Request parameters
- Name
tableId- Type
- string
- Description
The analytics table. For multi-table queries, the primary table; on the client API it must match the
resourceIdquery parameter.
- Name
limit- Type
- integer
- Description
Rows to return, up to 100. Default 50.
Response
- Name
columns- Type
- array<object>
- Description
Column
nameandtype, in order.
- Name
rows- Type
- array<object>
- Description
Rows as objects keyed by column name. See Values in results.
- cURL
- JavaScript
- Python
curl -X POST 'https://api.autessa.com/clients/autessadb/analytics/preview?resourceId=V1StGXR8Z5' \
-H "Authorization: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tableId": "V1StGXR8Z5",
"limit": 2
}'
const response = await fetch(
'https://api.autessa.com/clients/autessadb/analytics/preview?resourceId=V1StGXR8Z5',
{
method: 'POST',
headers: {
'Authorization': process.env.API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
tableId: 'V1StGXR8Z5',
limit: 2
})
}
);
const data = await response.json();
import os
import requests
response = requests.post(
'https://api.autessa.com/clients/autessadb/analytics/preview?resourceId=V1StGXR8Z5',
headers={'Authorization': os.environ['API_KEY']},
json={
'tableId': 'V1StGXR8Z5',
'limit': 2
}
)
data = response.json()
{
"columns": [
{
"name": "order_id",
"type": "LONG"
},
{
"name": "order_date",
"type": "DATE"
},
{
"name": "region",
"type": "STRING"
},
{
"name": "net_amount",
"type": "DECIMAL(18,2)"
}
],
"rows": [
{
"order_id": "90210331",
"order_date": "2026-10-01",
"region": "NA",
"net_amount": "129.00"
},
{
"order_id": "90210332",
"order_date": "2026-10-01",
"region": "EMEA",
"net_amount": "48.50"
}
]
}
Estimate a query
/estimateChecks a query and reports an upper bound on how much data it would scan, without running it. Use it to catch a missing partition filter before running an expensive query.
Permission: READ on every table the query references
Request parameters
- Name
tableId- Type
- string
- Description
The analytics table. For multi-table queries, the primary table; on the client API it must match the
resourceIdquery parameter.
- Name
sql- Type
- string
- Description
The query to estimate.
Response
- Name
estimatedBytesScanned- Type
- integer
- Description
Upper bound on data the query would read, after skipping partitions its filters rule out.
- Name
referencedTables- Type
- array<string>
- Description
SQL names of the tables the query reads.
- Name
withinLimits- Type
- boolean
- Description
falseif the estimate exceeds the per-query or remaining daily scan limit.
- Name
hint- Type
- string
- Description
When
withinLimitsisfalse: what to filter on, naming the partition columns.
- cURL
- JavaScript
- Python
curl -X POST 'https://api.autessa.com/clients/autessadb/analytics/estimate?resourceId=V1StGXR8Z5' \
-H "Authorization: $API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<'JSON'
{
"tableId": "V1StGXR8Z5",
"sql": "SELECT region, date_trunc('month', order_date) AS month, SUM(net_amount) AS revenue\nFROM order_lines\nWHERE order_date >= DATE '2026-01-01'\nGROUP BY 1, 2\nORDER BY 2, 1"
}
JSON
const response = await fetch(
'https://api.autessa.com/clients/autessadb/analytics/estimate?resourceId=V1StGXR8Z5',
{
method: 'POST',
headers: {
'Authorization': process.env.API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
tableId: 'V1StGXR8Z5',
sql: "SELECT region, date_trunc('month', order_date) AS month, SUM(net_amount) AS revenue\nFROM order_lines\nWHERE order_date >= DATE '2026-01-01'\nGROUP BY 1, 2\nORDER BY 2, 1"
})
}
);
const data = await response.json();
import os
import requests
response = requests.post(
'https://api.autessa.com/clients/autessadb/analytics/estimate?resourceId=V1StGXR8Z5',
headers={'Authorization': os.environ['API_KEY']},
json={
'tableId': 'V1StGXR8Z5',
'sql': "SELECT region, date_trunc('month', order_date) AS month, SUM(net_amount) AS revenue\nFROM order_lines\nWHERE order_date >= DATE '2026-01-01'\nGROUP BY 1, 2\nORDER BY 2, 1"
}
)
data = response.json()
{
"estimatedBytesScanned": 1288490188,
"referencedTables": [
"order_lines"
],
"withinLimits": true,
"hint": null
}
Run a query
/queryRuns a read-only SQL query as a job. If the job finishes within waitMs, the response includes the first rows; otherwise poll Get job status and then fetch results.
The query must be a single SELECT statement, optionally with WITH, written in ANSI SQL. It can read any analytics tables the caller has READ access to, by SQL name. Row-level and field-level security apply. Statements that change data or settings are rejected with FORBIDDEN_CONSTRUCT. SQL is limited to 100 KB.
Permission: READ on every table the query references
Request parameters
- Name
tableId- Type
- string
- Description
The analytics table. For multi-table queries, the primary table; on the client API it must match the
resourceIdquery parameter.
- Name
sql- Type
- string
- Description
The query.
- Name
maxRows- Type
- integer
- Description
Maximum rows to keep in the result. Capped at your plan's result-row limit; a larger result is cut off with
truncated: true.
- Name
maxBytesScanned- Type
- integer
- Description
Refuse to run if the estimate exceeds this many bytes. Cannot exceed your plan's per-query limit.
- Name
waitMs- Type
- integer
- Description
How long to wait for the job before returning, up to 20000.
0returns as soon as the job is queued.
Response
- Name
jobId- Type
- string
- Description
The job's ID.
- Name
state- Type
- string
- Description
QUEUED,RUNNING,SUCCEEDED,FAILED,CANCELLED, orTIMED_OUT.
- Name
bytesScanned- Type
- integer
- Description
Data read so far, in bytes.
- Name
elapsedMs- Type
- integer
- Description
Run time so far.
- Name
error- Type
- object
- Description
When the job failed:
errorCode,message, and ahintsuch as the valid column names. See Errors.
- Name
preview- Type
- object
- Description
When the job succeeded within
waitMs:columns, the first 200rows,totalRows, andtruncated(trueif the result hitmaxRows).
- cURL
- JavaScript
- Python
curl -X POST 'https://api.autessa.com/clients/autessadb/analytics/query?resourceId=V1StGXR8Z5' \
-H "Authorization: $API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<'JSON'
{
"tableId": "V1StGXR8Z5",
"sql": "SELECT region, date_trunc('month', order_date) AS month, SUM(net_amount) AS revenue\nFROM order_lines\nWHERE order_date >= DATE '2026-01-01'\nGROUP BY 1, 2\nORDER BY 2, 1",
"waitMs": 20000
}
JSON
const response = await fetch(
'https://api.autessa.com/clients/autessadb/analytics/query?resourceId=V1StGXR8Z5',
{
method: 'POST',
headers: {
'Authorization': process.env.API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
tableId: 'V1StGXR8Z5',
sql: "SELECT region, date_trunc('month', order_date) AS month, SUM(net_amount) AS revenue\nFROM order_lines\nWHERE order_date >= DATE '2026-01-01'\nGROUP BY 1, 2\nORDER BY 2, 1",
waitMs: 20000
})
}
);
const data = await response.json();
import os
import requests
response = requests.post(
'https://api.autessa.com/clients/autessadb/analytics/query?resourceId=V1StGXR8Z5',
headers={'Authorization': os.environ['API_KEY']},
json={
'tableId': 'V1StGXR8Z5',
'sql': "SELECT region, date_trunc('month', order_date) AS month, SUM(net_amount) AS revenue\nFROM order_lines\nWHERE order_date >= DATE '2026-01-01'\nGROUP BY 1, 2\nORDER BY 2, 1",
'waitMs': 20000
}
)
data = response.json()
{
"jobId": "1f8e5c3a-9b2d-4e7f-a6c1-3d0b9e2f7a54",
"state": "SUCCEEDED",
"bytesScanned": 402653184,
"elapsedMs": 2140,
"preview": {
"columns": [
{
"name": "region",
"type": "STRING"
},
{
"name": "month",
"type": "TIMESTAMPTZ"
},
{
"name": "revenue",
"type": "DECIMAL(18,2)"
}
],
"rows": [
{
"region": "EMEA",
"month": "2026-01-01T00:00:00Z",
"revenue": "1284410.50"
},
{
"region": "NA",
"month": "2026-01-01T00:00:00Z",
"revenue": "2390112.75"
}
],
"totalRows": 24,
"truncated": false
}
}
Get job status
/job-statusReturns a job's state, optionally waiting for it to finish. Jobs can be read by the caller who started them, or by anyone with READ on every table they reference.
Permission: READ
Request parameters
- Name
tableId- Type
- string
- Description
The analytics table. For multi-table queries, the primary table; on the client API it must match the
resourceIdquery parameter.
- Name
jobId- Type
- string
- Description
The job.
- Name
waitMs- Type
- integer
- Description
How long to wait for the job to finish before returning, up to 20000.
Response
- Name
jobId- Type
- string
- Description
The job's ID.
- Name
state- Type
- string
- Description
QUEUED,RUNNING,SUCCEEDED,FAILED,CANCELLED, orTIMED_OUT.
- Name
bytesScanned- Type
- integer
- Description
Data read so far, in bytes.
- Name
elapsedMs- Type
- integer
- Description
Run time so far.
- Name
error- Type
- object
- Description
When the job failed:
errorCode,message, and ahintsuch as the valid column names. See Errors.
- Name
resultRowCount- Type
- integer
- Description
Rows in the result, once succeeded.
- Name
truncated- Type
- boolean
- Description
trueif the result was cut off atmaxRows.
- Name
resultColumns- Type
- array<object>
- Description
Column
nameandtypeof the result.
- cURL
- JavaScript
- Python
curl -X POST 'https://api.autessa.com/clients/autessadb/analytics/job-status?resourceId=V1StGXR8Z5' \
-H "Authorization: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tableId": "V1StGXR8Z5",
"jobId": "1f8e5c3a-9b2d-4e7f-a6c1-3d0b9e2f7a54",
"waitMs": 10000
}'
const response = await fetch(
'https://api.autessa.com/clients/autessadb/analytics/job-status?resourceId=V1StGXR8Z5',
{
method: 'POST',
headers: {
'Authorization': process.env.API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
tableId: 'V1StGXR8Z5',
jobId: '1f8e5c3a-9b2d-4e7f-a6c1-3d0b9e2f7a54',
waitMs: 10000
})
}
);
const data = await response.json();
import os
import requests
response = requests.post(
'https://api.autessa.com/clients/autessadb/analytics/job-status?resourceId=V1StGXR8Z5',
headers={'Authorization': os.environ['API_KEY']},
json={
'tableId': 'V1StGXR8Z5',
'jobId': '1f8e5c3a-9b2d-4e7f-a6c1-3d0b9e2f7a54',
'waitMs': 10000
}
)
data = response.json()
{
"jobId": "1f8e5c3a-9b2d-4e7f-a6c1-3d0b9e2f7a54",
"state": "SUCCEEDED",
"bytesScanned": 402653184,
"elapsedMs": 2140,
"resultRowCount": 24,
"truncated": false,
"resultColumns": [
{
"name": "region",
"type": "STRING"
},
{
"name": "month",
"type": "TIMESTAMPTZ"
},
{
"name": "revenue",
"type": "DECIMAL(18,2)"
}
]
}
Get job results
/job-resultsReturns one page of a finished job's result. Results are kept for 7 days.
Permission: READ
Request parameters
- Name
tableId- Type
- string
- Description
The analytics table. For multi-table queries, the primary table; on the client API it must match the
resourceIdquery parameter.
- Name
jobId- Type
- string
- Description
The job.
- Name
page- Type
- integer
- Description
Page number, starting at 0.
- Name
pageSize- Type
- integer
- Description
Rows per page, up to 1000. Default 1000.
Response
- Name
columns- Type
- array<object>
- Description
Column
nameandtype.
- Name
rows- Type
- array<object>
- Description
Rows as objects keyed by column name. See Values in results.
- Name
page- Type
- integer
- Description
This page.
- Name
totalRows- Type
- integer
- Description
Rows in the whole result.
- Name
hasMore- Type
- boolean
- Description
trueif later pages exist.
- Name
truncated- Type
- boolean
- Description
trueif the result itself was cut off atmaxRows.
- cURL
- JavaScript
- Python
curl -X POST 'https://api.autessa.com/clients/autessadb/analytics/job-results?resourceId=V1StGXR8Z5' \
-H "Authorization: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tableId": "V1StGXR8Z5",
"jobId": "1f8e5c3a-9b2d-4e7f-a6c1-3d0b9e2f7a54",
"page": 0,
"pageSize": 1000
}'
const response = await fetch(
'https://api.autessa.com/clients/autessadb/analytics/job-results?resourceId=V1StGXR8Z5',
{
method: 'POST',
headers: {
'Authorization': process.env.API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
tableId: 'V1StGXR8Z5',
jobId: '1f8e5c3a-9b2d-4e7f-a6c1-3d0b9e2f7a54',
page: 0,
pageSize: 1000
})
}
);
const data = await response.json();
import os
import requests
response = requests.post(
'https://api.autessa.com/clients/autessadb/analytics/job-results?resourceId=V1StGXR8Z5',
headers={'Authorization': os.environ['API_KEY']},
json={
'tableId': 'V1StGXR8Z5',
'jobId': '1f8e5c3a-9b2d-4e7f-a6c1-3d0b9e2f7a54',
'page': 0,
'pageSize': 1000
}
)
data = response.json()
{
"columns": [
{
"name": "region",
"type": "STRING"
},
{
"name": "month",
"type": "TIMESTAMPTZ"
},
{
"name": "revenue",
"type": "DECIMAL(18,2)"
}
],
"rows": [
{
"region": "EMEA",
"month": "2026-01-01T00:00:00Z",
"revenue": "1284410.50"
},
{
"region": "NA",
"month": "2026-01-01T00:00:00Z",
"revenue": "2390112.75"
}
],
"page": 0,
"totalRows": 24,
"hasMore": false,
"truncated": false
}
Download job results
/job-download-urlReturns a short-lived link to download a finished job's full result. Only the caller who ran the job can download it.
Permission: READ
Request parameters
- Name
tableId- Type
- string
- Description
The analytics table. For multi-table queries, the primary table; on the client API it must match the
resourceIdquery parameter.
- Name
jobId- Type
- string
- Description
The job.
- Name
format- Type
- string
- Description
CSV(default) orPARQUET.
Response
- Name
url- Type
- string
- Description
The download link.
- Name
expiresAt- Type
- string
- Description
When the link stops working, 5 minutes after it is issued.
- cURL
- JavaScript
- Python
curl -X POST 'https://api.autessa.com/clients/autessadb/analytics/job-download-url?resourceId=V1StGXR8Z5' \
-H "Authorization: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tableId": "V1StGXR8Z5",
"jobId": "1f8e5c3a-9b2d-4e7f-a6c1-3d0b9e2f7a54",
"format": "CSV"
}'
const response = await fetch(
'https://api.autessa.com/clients/autessadb/analytics/job-download-url?resourceId=V1StGXR8Z5',
{
method: 'POST',
headers: {
'Authorization': process.env.API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
tableId: 'V1StGXR8Z5',
jobId: '1f8e5c3a-9b2d-4e7f-a6c1-3d0b9e2f7a54',
format: 'CSV'
})
}
);
const data = await response.json();
import os
import requests
response = requests.post(
'https://api.autessa.com/clients/autessadb/analytics/job-download-url?resourceId=V1StGXR8Z5',
headers={'Authorization': os.environ['API_KEY']},
json={
'tableId': 'V1StGXR8Z5',
'jobId': '1f8e5c3a-9b2d-4e7f-a6c1-3d0b9e2f7a54',
'format': 'CSV'
}
)
data = response.json()
{
"url": "https://files.autessa.com/r/1f8e5c3a.../result.csv",
"expiresAt": "2026-10-02T15:05:00Z"
}
Cancel a job
/cancelCancels a queued or running job. A running job stops within a few seconds.
Permission: READ, and the caller must have started the job
Request parameters
- Name
tableId- Type
- string
- Description
The analytics table. For multi-table queries, the primary table; on the client API it must match the
resourceIdquery parameter.
- Name
jobId- Type
- string
- Description
The job.
Response
- Name
jobId- Type
- string
- Description
The job.
- Name
state- Type
- string
- Description
CANCELLED, or the final state if the job had already finished.
- cURL
- JavaScript
- Python
curl -X POST 'https://api.autessa.com/clients/autessadb/analytics/cancel?resourceId=V1StGXR8Z5' \
-H "Authorization: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tableId": "V1StGXR8Z5",
"jobId": "1f8e5c3a-9b2d-4e7f-a6c1-3d0b9e2f7a54"
}'
const response = await fetch(
'https://api.autessa.com/clients/autessadb/analytics/cancel?resourceId=V1StGXR8Z5',
{
method: 'POST',
headers: {
'Authorization': process.env.API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
tableId: 'V1StGXR8Z5',
jobId: '1f8e5c3a-9b2d-4e7f-a6c1-3d0b9e2f7a54'
})
}
);
const data = await response.json();
import os
import requests
response = requests.post(
'https://api.autessa.com/clients/autessadb/analytics/cancel?resourceId=V1StGXR8Z5',
headers={'Authorization': os.environ['API_KEY']},
json={
'tableId': 'V1StGXR8Z5',
'jobId': '1f8e5c3a-9b2d-4e7f-a6c1-3d0b9e2f7a54'
}
)
data = response.json()
{
"jobId": "1f8e5c3a-9b2d-4e7f-a6c1-3d0b9e2f7a54",
"state": "CANCELLED"
}
List jobs
/jobsLists recent jobs on a table, newest first: queries, loads, and appends.
Permission: READ
Request parameters
- Name
tableId- Type
- string
- Description
The analytics table. For multi-table queries, the primary table; on the client API it must match the
resourceIdquery parameter.
- Name
kind- Type
- string
- Description
Only this kind:
QUERY,LOAD, orAPPEND.
- Name
state- Type
- string
- Description
Only jobs in this state.
- Name
mine- Type
- boolean
- Description
Only jobs the caller started. Default
false.
- Name
limit- Type
- integer
- Description
Jobs per page, up to 100. Default 25.
- Name
cursor- Type
- string
- Description
The
nextCursorfrom the previous page.
Response
- Name
jobs- Type
- array<object>
- Description
Each job:
jobId,kind,state,sql(first 500 characters),createdBy,createdAt,finishedAt,resultRowCount,bytesScanned, andelapsedMs.
- Name
nextCursor- Type
- string
- Description
Cursor for the next page, or
null.
- cURL
- JavaScript
- Python
curl -X POST 'https://api.autessa.com/clients/autessadb/analytics/jobs?resourceId=V1StGXR8Z5' \
-H "Authorization: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tableId": "V1StGXR8Z5",
"kind": "QUERY",
"limit": 1
}'
const response = await fetch(
'https://api.autessa.com/clients/autessadb/analytics/jobs?resourceId=V1StGXR8Z5',
{
method: 'POST',
headers: {
'Authorization': process.env.API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
tableId: 'V1StGXR8Z5',
kind: 'QUERY',
limit: 1
})
}
);
const data = await response.json();
import os
import requests
response = requests.post(
'https://api.autessa.com/clients/autessadb/analytics/jobs?resourceId=V1StGXR8Z5',
headers={'Authorization': os.environ['API_KEY']},
json={
'tableId': 'V1StGXR8Z5',
'kind': 'QUERY',
'limit': 1
}
)
data = response.json()
{
"jobs": [
{
"jobId": "1f8e5c3a-9b2d-4e7f-a6c1-3d0b9e2f7a54",
"kind": "QUERY",
"state": "SUCCEEDED",
"sql": "SELECT region, date_trunc('month', order_date) AS month, SUM(net_amount) AS revenue\nFROM order_lines\nWHERE order_date >= DATE '2026-01-01'\nGROUP BY 1, 2\nORDER BY 2, 1",
"createdBy": {
"userId": "u8Kd2LmQ4x",
"name": "Dana Ortiz"
},
"createdAt": "2026-10-02T14:59:51Z",
"finishedAt": "2026-10-02T14:59:53Z",
"resultRowCount": 24,
"bytesScanned": 402653184,
"elapsedMs": 2140
}
],
"nextCursor": "eyJ0IjoiMjAyNi0xMC0wMlQxNDo1OTo1MVoifQ"
}
Load files
/load-from-s3Loads one or more CSV or Parquet files into the table as a job. Upload each file first (see Uploading a file to load) and pass the s3Uri you get back. Values are converted to the column types; rows that cannot be converted are counted and sampled in the job result rather than silently dropped. A load is all-or-nothing: if it fails, no rows are added.
Permission: WRITE
Request parameters
- Name
tableId- Type
- string
- Description
The analytics table. For multi-table queries, the primary table; on the client API it must match the
resourceIdquery parameter.
- Name
sourceUris- Type
- array<string>
- Description
The uploaded files'
s3Urivalues.
- Name
format- Type
- string
- Description
CSVorPARQUET. Inferred from the file extension when omitted.
- Name
mode- Type
- string
- Description
APPEND(default) adds the rows;REPLACEswaps the table's contents for them.
- Name
csv- Type
- object
- Description
CSV options:
delimiter(default,),header(defaulttrue),nullString,quote,dateFormat, andtimestampFormat.
- Name
columnMapping- Type
- object
- Description
Map of file column name to table column name, when they differ. Unmapped table columns are left empty.
Response
- Name
jobId- Type
- string
- Description
The load job. Poll Get job status; a finished load reports
rowsLoaded,rowsRejected, andrejectedSample.
- Name
state- Type
- string
- Description
The job's state.
- cURL
- JavaScript
- Python
curl -X POST 'https://api.autessa.com/clients/autessadb/analytics/load-from-s3?resourceId=V1StGXR8Z5' \
-H "Authorization: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tableId": "V1StGXR8Z5",
"sourceUris": [
"s3://autessa-intake/cP2mK7dX4v/9a1e.../orders-2026-09.csv"
],
"format": "CSV",
"mode": "APPEND",
"csv": {
"header": true,
"timestampFormat": "%Y-%m-%d %H:%M:%S"
}
}'
const response = await fetch(
'https://api.autessa.com/clients/autessadb/analytics/load-from-s3?resourceId=V1StGXR8Z5',
{
method: 'POST',
headers: {
'Authorization': process.env.API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
tableId: 'V1StGXR8Z5',
sourceUris: ['s3://autessa-intake/cP2mK7dX4v/9a1e.../orders-2026-09.csv'],
format: 'CSV',
mode: 'APPEND',
csv: {
header: true,
timestampFormat: '%Y-%m-%d %H:%M:%S'
}
})
}
);
const data = await response.json();
import os
import requests
response = requests.post(
'https://api.autessa.com/clients/autessadb/analytics/load-from-s3?resourceId=V1StGXR8Z5',
headers={'Authorization': os.environ['API_KEY']},
json={
'tableId': 'V1StGXR8Z5',
'sourceUris': ['s3://autessa-intake/cP2mK7dX4v/9a1e.../orders-2026-09.csv'],
'format': 'CSV',
'mode': 'APPEND',
'csv': {
'header': True,
'timestampFormat': '%Y-%m-%d %H:%M:%S'
}
}
)
data = response.json()
{
"jobId": "6c2b9e14-3f7a-4d81-b0e5-a9d4c2f81b37",
"state": "QUEUED"
}
Append rows
/append-rowsAppends a small batch of rows sent in the request body: up to 10,000 rows or 5 MB per call. Appends that arrive within a few seconds of each other are committed together, so rows become visible to queries within about 5 seconds. Use Load files for bulk data.
Permission: WRITE
Request parameters
- Name
tableId- Type
- string
- Description
The analytics table. For multi-table queries, the primary table; on the client API it must match the
resourceIdquery parameter.
- Name
rows- Type
- array<object>
- Description
Rows as objects keyed by column name, with plain JSON values. Send
DECIMALand large integers as strings, dates and timestamps as ISO-8601 strings.
Response
- Name
accepted- Type
- integer
- Description
Rows accepted.
- Name
loadId- Type
- string
- Description
Identifier written to the
_load_idcolumn of these rows.
- Name
errors- Type
- array<object>
- Description
Rows refused:
indexandmessage. Refused rows are not appended; the others are.
- cURL
- JavaScript
- Python
curl -X POST 'https://api.autessa.com/clients/autessadb/analytics/append-rows?resourceId=V1StGXR8Z5' \
-H "Authorization: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tableId": "V1StGXR8Z5",
"rows": [
{
"order_id": "90210333",
"order_date": "2026-10-02",
"region": "APAC",
"net_amount": "310.00"
}
]
}'
const response = await fetch(
'https://api.autessa.com/clients/autessadb/analytics/append-rows?resourceId=V1StGXR8Z5',
{
method: 'POST',
headers: {
'Authorization': process.env.API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
tableId: 'V1StGXR8Z5',
rows: [
{
order_id: '90210333',
order_date: '2026-10-02',
region: 'APAC',
net_amount: '310.00'
}
]
})
}
);
const data = await response.json();
import os
import requests
response = requests.post(
'https://api.autessa.com/clients/autessadb/analytics/append-rows?resourceId=V1StGXR8Z5',
headers={'Authorization': os.environ['API_KEY']},
json={
'tableId': 'V1StGXR8Z5',
'rows': [
{
'order_id': '90210333',
'order_date': '2026-10-02',
'region': 'APAC',
'net_amount': '310.00'
}
]
}
)
data = response.json()
{
"accepted": 1,
"loadId": "append-2026-10-02T15:00:05Z",
"errors": []
}
Masked columns
Text columns created with masked: true are stored encrypted and appear in results as mask text unless the caller's role allows revealing them.
createandadd-columns:columns[].masked: true(STRING only).describe:columns[].encrypted,revealable, andmaskStrategy.query,preview,job-results, andjob-download-urlacceptreveal: trueto return plaintext for callers whose role shows the column; every reveal is recorded in the access log.job-resultsalso acceptsrevealRow(0-based row of the whole result) withrevealColumnand returnsrevealedCell {row, column, value}for a single cell.- Result
columns[]carrymasked,revealable,revealed, andmaskStrategy. - In SQL, masked columns support
=,<>,IN,IS NULL,GROUP BY,DISTINCT,COUNT(DISTINCT),MIN/MAX, joins with other masked columns, andORDER BY(by an internal code).LIKE, ranges, and other functions fail withFORBIDDEN_CONSTRUCTand a hint. - Loads into tables with masked columns run in the app rather than the analytics engine; load responses say so in
notes.
Errors
Failed calls, and jobs that end in FAILED or TIMED_OUT, carry an error code, a plain-language message, and where possible a hint:
{
"errorCode": "UNKNOWN_COLUMN",
"errors": ["Column \"net_amt\" does not exist in order_lines."],
"hint": "Columns in order_lines: order_id, order_date, region, customer_id, net_amount."
}
| Error code | When |
|---|---|
PARSE_ERROR | The SQL could not be parsed. The message points at the position. |
FORBIDDEN_CONSTRUCT | The SQL is not a single read-only query: it changes data or settings, has several statements, or calls a function that reads files or system state. |
UNKNOWN_TABLE | The query names a table that does not exist or that the caller cannot read. The two cases are reported the same way. |
UNKNOWN_COLUMN | The query names a column that does not exist or is hidden from the caller. The hint lists the available columns. |
SCAN_LIMIT | The query would scan more than the per-query limit, maxBytesScanned, or the remaining daily allowance. The hint names the partition columns to filter on. |
TIMEOUT | The query ran past the time limit. |
ROW_LIMIT | Too many rows were requested; lower maxRows or pageSize. |
QUOTA | A plan limit was reached: storage, concurrent queries, data loaded per day, or appended rows per minute. |
VERSION_CONFLICT | The semantic layer changed since expectedVersion. Describe again and retry. |
INVALID_SCHEMA | A column name, type, or partition spec is invalid, or a schema change is not a safe widening. |
FORBIDDEN | The caller lacks the table permission for the operation, or the job belongs to another caller. |
NOT_FOUND | The table or job does not exist, or its results have expired. |
HTTP status codes follow the usual pattern: 400 for invalid requests and SQL errors, 401 for a missing or invalid key, 403 for FORBIDDEN, 404 for NOT_FOUND, 409 for VERSION_CONFLICT, 413 for SCAN_LIMIT and ROW_LIMIT, and 429 for QUOTA and rate limits.