How it works
Onboarding is four calls. Each one feeds the next:All paths are relative to your controller base URL. The examples assume
export CONTROLLER=https://<your-controller>. On StarTree Cloud, the controller is reached through the data-plane proxy, so use export CONTROLLER=https://<data-plane-host>/api/pinot.If your controller requires authentication, add an Authorization header to every request — e.g. -H "Authorization: Bearer <token>". The examples below omit it for brevity.Prerequisites
- StarTree 0.15.0 or later with the External Table Beta feature enabled, and tiered storage configured on the cluster. Contact StarTree support if unsure.
- Network access to the controller REST endpoint, plus an
Authorizationtoken if your cluster requires auth. - AWS credentials (access key + secret key) with
s3:GetObjectands3:ListBucketon the source bucket and prefix. - The S3 bucket name, key prefix, and region.
Limitations
- No catalog metadata — namespace and table names are values you choose, not read from a catalog; browse only validates the connection and lists files/directories.
- No schema evolution. Raw Parquet has no Iceberg field-id history to key a rename against, so a source-side column rename always requires a manual schema change (unlike
catalogType=iceberg-restsources withschemaEvolution.enabled=true). catalog.s3.prefixis a permanent filter, not a starting cursor — see the Warning further down this page, under thecatalog.s3.*reference table, before using it to try to skip ahead in a large bucket.
Authentication
Unlike the Iceberg-catalog sources, there’s only one auth surface here —catalog.s3.* covers both listing the bucket and reading the Parquet data. Choose one of three credential methods.
The role or keys need s3:GetObject and s3:ListBucket on the source bucket and prefix. Verify from the cluster before onboarding:
Assumed IAM role (recommended for production)
No static secrets in the table config — every S3 call assumesroleArn via STS.
Cluster node role
OmitroleArn/accessKey/secretKey entirely — only bucketName, prefix, and region are required. Credential resolution falls back to the AWS SDK default chain (the node’s instance profile / IRSA role), which must already have access to the bucket.
Static access keys
Quick tests, or when role-based access isn’t available.catalog.s3.* reference
Step 1: Validate and browse the connection
POST /connections/browse
There is no separate “validate” endpoint. Browsing the catalog is the validation step: a 200 with an items list (even an empty one) confirms your credentials and connectivity. Bad credentials or an unreachable prefix return an error.
- Set
pathto""to browse the root prefix — this both validates the connection and lists files/directories.
Request
Response
Step 2: Preview the schema
POST /tables/preview
Samples the Parquet files, infers a Pinot schema, and returns an enriched table config (S3 tier, raw field configs, time column) plus sample rows. Review it, tweak if needed, then carry the schema and config forward to steps 3 and 4.
The request and response share the same JSON shape. You send a
tableConfig describing the source; the response fills in schema, the enriched tableConfigs.offline, sampled rows, and a summary.Request
Top-level fields:config.inference — how the schema is derived:
config.sampling — how rows are sampled:
Setting the namespace and table. For S3, browse only validates the connection and lists files; the names are values you choose — set
catalog.s3.table.namespace (use default for a flat prefix) and catalog.s3.table.tableName (any logical name).Use executor: controller — it’s required for the controller-watcher flow and the observability endpoints. The input tableConfig is intentionally minimal; /tables/preview returns the complete tableConfigs.offline you persist in Step 4.Response
Adjust the schema (time column, column names, null handling) before moving on.
Step 3: Create the schema
POST /schemas
Send the schema object from the preview response. Rename its schemaName to match your table.
Step 4: Create the table
POST /tables
Send the enriched tableConfigs.offline object from the preview response. Its ExternalTableSyncTask block is what marks the table as external.
schedule (cron) interval. There is no separate start call.
Quickstart: onboard a table end-to-end
The whole flow as one script. Fill in the variables at the top, run the script, and the first sync starts automatically.0, verify it’s queryable.
Monitor onboarding
Three read-only endpoints report ingestion progress — run status, ingestion checkpoint, and source file count — and requireexecutor=controller (set automatically). See Observability for full request and response details.
Verify it’s queryable
Whenstatus is COMPLETED and segmentsUploaded matches filesDiscovered, run a query against the broker (or the Data Portal query console) to confirm the data is live:
summary.nSourceRows (preview only samples up to ~100 rows) — confirm it’s non-zero and plausible for your dataset. If status is COMPLETED but the count is 0, give segments a moment to load on the servers, then recheck; if it persists, see Troubleshooting.
What’s next
Now that the table is created and data is loading, these are the highest-impact follow-up steps:- Add indexes for your query patterns. Without indexes, every query scans all remote Parquet data. Add a range index on time/numeric columns, an inverted index on low-cardinality filter columns, and a bloom filter on high-cardinality ID columns. → Indexes
-
Enable caching and preload. Set
enable.prefetch.page.cache=trueandpreload.enable=trueon the S3 tier so index data is served from local disk on repeated queries instead of re-fetched from S3. → Data and Index Caching - Protect large-scan queries from OOM. For tables that receive heavy aggregations or wide scans, enable the query OOM killer so a runaway query is killed instead of crashing the server. → Best Practices & Configs — Query OOM protection
- Monitor ongoing syncs. Use the observability endpoints to check run status, ingestion checkpoint, and source file count after each scheduled sync. → Observability
For common questions and failures, see the FAQ and Troubleshooting.

