Browse docs
API ReferenceUpdated August 21, 2024

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

  1. Start — POST your query to /query/async. The server returns a job_id and status_url.
  2. Poll — GET the status_url to check progress. The response includes query_status (Queued, Running, Completed, or Failed) and a progress_pct field.
  3. Download — When the status is Completed, the response includes a download_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