Query
The Query API allows you to retrieve data from Telemetry. It accepts basic SQL, enabling you to query all available data using commands such as JOINS and UNIONS. These queries can return a wide range of data, from system metrics to user engagement.
POST https://api.telemetry.sh/query
Headers
| Name | Type | Description |
|---|---|---|
| Content-Type | String | application/json |
| Authorization | String | <YOUR_API_KEY> |
Body
| Name | Type | Description |
|---|---|---|
| query | String | SQL Query you want to run |
Example usage with cURL
To query the average Uber price grouped by city from the table named uber_rides using cURL, you can use the following command:
curl -X POST https://api.telemetry.sh/query \
-H "Content-Type: application/json" \
-H "Authorization: $API_KEY" \
-d ‘{
"query": "
SELECT
city,
AVG(price) AS average_price
FROM
uber_rides
GROUP BY
city
LIMIT
10000;
"
}’
Using the JavaScript SDK
We recommend using our SDKs for a better developer experience. Here’s an example of how to use our JavaScript SDK:
const results =
await telemetry.query(`
SELECT
city,
AVG(price)
FROM
uber_rides
GROUP BY
city
`);
Async Query
For long-running queries or large result sets, you can use the async query API. Instead of waiting for the full result inline, the server returns a job reference that you poll until the query completes. Once finished, you get a presigned download URL to fetch the results.
This is especially useful for exporting entire tables, running heavy aggregations, or downloading results as Parquet files.
How it works
- Start — POST your query to
/query/async. The server returns ajob_idandstatus_url. - Poll — GET the
status_urlto check progress. The response includesquery_status(Queued,Running,Completed, orFailed) and aprogress_pctfield. - Download — When the status is
Completed, the response includes adownload_url(a presigned URL) where you can fetch the results.
API Reference
Start an async query
POST https://api.telemetry.sh/query/async
Headers
| Name | Type | Description |
|---|---|---|
| Content-Type | String | application/json |
| Authorization | String | <YOUR_API_KEY> |
Body
| Name | Type | Description |
|---|---|---|
| query | String | SQL query you want to run |
| format | String | Result format: "json" (default) or "parquet" |
Response (202 Accepted)
{
"status": "accepted",
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"format": "json",
"status_url": "/query/async/550e8400-e29b-41d4-a716-446655440000"
}
Poll query status
GET https://api.telemetry.sh/query/async/{job_id}
Headers
| Name | Type | Description |
|---|---|---|
| Authorization | String | <YOUR_API_KEY> |
Response (200 OK)
{
"status": "success",
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"query_status": "Completed",
"format": "json",
"progress_pct": 100,
"message": "Query completed",
"created_at": "2025-02-24T12:00:00Z",
"completed_at": "2025-02-24T12:00:05Z",
"download_url": "https://storage.example.com/results/...",
"download_url_expires_in_seconds": 3600
}
The query_status field will be one of:
| Status | Description |
|---|---|
Queued |
The query is waiting to be executed |
Running |
The query is currently executing |
Completed |
Results are ready to download via download_url |
Failed |
The query failed — check the error field |
Async query with cURL
# 1. Start the async query
RESPONSE=$(curl -s -X POST https://api.telemetry.sh/query/async \
-H "Content-Type: application/json" \
-H "Authorization: $API_KEY" \
-d ‘{
"query": "SELECT * FROM uber_rides",
"format": "json"
}’)
STATUS_URL="https://api.telemetry.sh$(echo $RESPONSE | jq -r ‘.status_url’)"
# 2. Poll until complete
while true; do
STATUS=$(curl -s -H "Authorization: $API_KEY" "$STATUS_URL")
QUERY_STATUS=$(echo $STATUS | jq -r ‘.query_status’)
echo "Status: $QUERY_STATUS"
if [ "$QUERY_STATUS" = "Completed" ]; then
DOWNLOAD_URL=$(echo $STATUS | jq -r ‘.download_url’)
break
elif [ "$QUERY_STATUS" = "Failed" ]; then
echo "Query failed: $(echo $STATUS | jq -r ‘.error’)"
exit 1
fi
sleep 5
done
# 3. Download results
curl -o results.json "$DOWNLOAD_URL"
Example: Exporting an entire table
The async query API is ideal for full table exports. Since there’s no row limit on async queries, you can export everything and download the result as a single file.
# Start the export as Parquet
RESPONSE=$(curl -s -X POST https://api.telemetry.sh/query/async \
-H "Content-Type: application/json" \
-H "Authorization: $API_KEY" \
-d ‘{
"query": "SELECT * FROM uber_rides",
"format": "parquet"
}’)
STATUS_URL="https://api.telemetry.sh$(echo $RESPONSE | jq -r ‘.status_url’)"
# Poll until complete
while true; do
STATUS=$(curl -s -H "Authorization: $API_KEY" "$STATUS_URL")
QUERY_STATUS=$(echo $STATUS | jq -r ‘.query_status’)
if [ "$QUERY_STATUS" = "Completed" ]; then
curl -o uber_rides_export.parquet "$(echo $STATUS | jq -r ‘.download_url’)"
echo "Export complete: uber_rides_export.parquet"
break
elif [ "$QUERY_STATUS" = "Failed" ]; then
echo "Export failed: $(echo $STATUS | jq -r ‘.error’)"
exit 1
fi
sleep 5
done