Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.siftstack.com/llms.txt

Use this file to discover all available pages before exploring further.

Sift’s REST API and client libraries let you export telemetry data from Runs programmatically for use in external tools, custom pipelines, and downstream analysis environments such as MATLAB or Python. Official clients are available for Python, Rust, and Go. Clients for other languages can be generated using Buf. Data captured from a Run can also be exported directly from the UI without writing code, in CSV, Parquet, or Sun (WinPlot) format.

Before you export

To export data from Sift programmatically, make sure you have the following:

How does programmatic export work

Sift provides two programmatic export mechanisms, each available through the REST API and client libraries.

Supported clients

Official clients are available for the following languages: Clients for other languages can be generated using Buf.

Mechanisms

The table below compares both mechanisms across the REST API and client libraries.

Mechanism 1: Data querying

Data querying requests Channel data over a defined time window and returns the response immediately. Available via POST /api/v2/data in the REST API, through the official Python, Rust, and Go clients, and through any client generated using Buf.

REST API

The examples below use cURL to call POST /api/v2/data (GetData) directly. See the GetData endpoint reference for the full schema.
1

Query Channel data

curl --request POST \
  --url "https://api.siftstack.com/api/v2/data" \
  --header "Authorization: Bearer $SIFT_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "queries": [
      {
        "channel": {
          "channelId": "YOUR_CHANNEL_ID_1",
          "runId": "YOUR_RUN_ID"
        }
      },
      {
        "channel": {
          "channelId": "YOUR_CHANNEL_ID_2",
          "runId": "YOUR_RUN_ID"
        }
      }
    ],
    "startTime": "2026-03-13T19:43:25.557Z",
    "endTime": "2026-03-13T19:48:25.557Z",
    "sampleMs": 100,
    "pageSize": 100000,
    "pageToken": ""
  }'
2

Paginate if needed

If the response includes a non-empty nextPageToken, resend the same request with pageToken set to that value to retrieve the next batch. Repeat until nextPageToken comes back empty.
curl --request POST \
  --url "https://api.siftstack.com/api/v2/data" \
  --header "Authorization: Bearer $SIFT_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "queries": [
      {
        "channel": {
          "channelId": "YOUR_CHANNEL_ID_1",
          "runId": "YOUR_RUN_ID"
        }
      }
    ],
    "startTime": "2026-03-13T19:43:25.557Z",
    "endTime": "2026-03-13T19:48:25.557Z",
    "sampleMs": 100,
    "pageSize": 100000,
    "pageToken": "TOKEN_FROM_PREVIOUS_RESPONSE"
  }'

Python client

The official Python client provides two methods for querying Channel data:
1

Initialize the client

import os
from datetime import datetime, timezone
from dotenv import load_dotenv
from sift_client import SiftClient
load_dotenv()

client = SiftClient(
    api_key=os.getenv("SIFT_API_KEY"),
    grpc_url=os.getenv("SIFT_GRPC_URI"),
    rest_url=os.getenv("SIFT_REST_URI"),
)
2

Retrieve the data

Fetch the Channel object using its ID, then call client.channels.get_data_as_arrow(). The method returns a dict where each key is a Channel name and the value is an Apache Arrow table.
channel = client.channels.get(channel_id="YOUR_CHANNEL_ID")

result = client.channels.get_data_as_arrow(
    channels=[channel],
    run="YOUR_RUN_ID",
    start_time=datetime(YYYY, MM, DD, HH, MM, SS, microsecond, tzinfo=timezone.utc),  # e.g. datetime(2026, 4, 15, 0, 17, 49, 984000, tzinfo=timezone.utc) = 2026-04-15T00:17:49.984Z
    end_time=datetime(YYYY, MM, DD, HH, MM, SS, microsecond, tzinfo=timezone.utc),    # e.g. datetime(2026, 4, 15, 0, 18, 26, 609000, tzinfo=timezone.utc) = 2026-04-15T00:18:26.609Z
)

# Access the table by Channel name and convert to a pandas DataFrame
df = result["YOUR_CHANNEL_NAME"].to_pandas()
Or using client.channels.get_data(), which returns a dict[str, pd.DataFrame] directly with no conversion needed:
result = client.channels.get_data(
    channels=[channel],
    run="YOUR_RUN_ID",
    start_time=datetime(YYYY, MM, DD, HH, MM, SS, microsecond, tzinfo=timezone.utc),  # e.g. datetime(2026, 4, 15, 0, 17, 49, 984000, tzinfo=timezone.utc) = 2026-04-15T00:17:49.984Z
    end_time=datetime(YYYY, MM, DD, HH, MM, SS, microsecond, tzinfo=timezone.utc),    # e.g. datetime(2026, 4, 15, 0, 18, 26, 609000, tzinfo=timezone.utc) = 2026-04-15T00:18:26.609Z
)

# Access the DataFrame by Channel name
df = result["YOUR_CHANNEL_NAME"]

Mechanism 2: Export data to file

Export data to file processes the export in the background and makes the result available as a downloadable ZIP file. Supported output formats: CSV, Parquet, and Sun/WinPlot. Sun/WinPlot is feature-flagged and only available to certain gov cloud customers. Available via POST /api/v1/export in the REST API, through the official Python, Rust, and Go clients, and through any client generated using Buf.

REST API

The examples below use cURL to call POST /api/v1/export (ExportData) and GET /api/v1/export//download-url (GetDownloadUrl) directly. See the ExportData endpoint reference and the GetDownloadUrl endpoint reference for the full schema.
1

Submit the export job

curl --request POST \
  --url "https://api.siftstack.com/api/v1/export" \
  --header "Authorization: Bearer $SIFT_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "runsAndTimeRange": {
      "runIds": ["YOUR_RUN_ID"]
    },
    "channelIds": ["CHANNEL_ID_1", "CHANNEL_ID_2"],
    "outputFormat": "EXPORT_OUTPUT_FORMAT_PARQUET"
  }'
2

Retrieve the download link

If the response includes a presignedUrl, the export completed immediately and the file is ready to download. If the response includes a jobId instead, poll this endpoint until presignedUrl is populated:
curl --request GET \
  --url "https://api.siftstack.com/api/v1/export/YOUR_JOB_ID/download-url" \
  --header "Authorization: Bearer $SIFT_API_KEY"

Python client

The official Python client provides two methods for exporting data to file:
1

Initialize the client

import os
from dotenv import load_dotenv
from sift_client import SiftClient
from sift_client.sift_types.export import ExportOutputFormat

load_dotenv()

client = SiftClient(
    api_key=os.getenv("SIFT_API_KEY"),
    grpc_url=os.getenv("SIFT_GRPC_URI"),
    rest_url=os.getenv("SIFT_REST_URI"),
)
2

Submit the export job and download the result

job = client.data_export.export(
    output_format=ExportOutputFormat.PARQUET,  # or ExportOutputFormat.CSV, ExportOutputFormat.SUN
    runs=["YOUR_RUN_ID"],
    channels=["YOUR_CHANNEL_ID_1", "YOUR_CHANNEL_ID_2"],
)

paths = job.wait_and_download(output_dir=".")  # downloads and extracts to the directory where the script is run