> ## Documentation Index
> Fetch the complete documentation index at: https://docs-old.tilebox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Querying data

> Access and filter data stored in your datasets by time, location, and custom fields, with built-in pagination and progress tracking.

Tilebox offers a powerful and flexible querying API to access and filter data from your datasets. When querying, you can
[filter by time](https://docs-old.tilebox.com/datasets/query/filter-by-time.md), [filter by custom fields](https://docs-old.tilebox.com/datasets/query/filter-by-fields.md), and for
[Spatio-temporal datasets](https://docs-old.tilebox.com/datasets/types/spatiotemporal.md), optionally [filter by a location in the form of a geometry](https://docs-old.tilebox.com/datasets/query/filter-by-location.md).

## Running a query

You can query data from either a specific collection of a dataset, from a selected set of collections of a dataset, or from all collections of a dataset at once.
Below is a simple example showcasing those options by querying Sentinel-2 data for April 2025 over the state of Colorado.

```python Python theme={"system"}
from shapely import Polygon
from tilebox.datasets import Client

area = Polygon(  # area roughly covering the state of Colorado
    ((-109.05, 41.00), (-109.045, 37.0), (-102.05, 37.0), (-102.05, 41.00), (-109.05, 41.00)),
)

client = Client()
sentinel2_msi = client.dataset("open_data.copernicus.sentinel2_msi")

# query data from a specific collection
collection = sentinel2_msi.collection("S2A_S2MSI2A")
data = collection.query(
    temporal_extent=("2025-04-01", "2025-05-01"),
    spatial_extent=area,
    show_progress=True,
)

# query data from a selected set of collections
data = sentinel2_msi.query(
    collections=["S2A_S2MSI2A", "S2B_S2MSI2A", "S2C_S2MSI2A"],
    temporal_extent=("2025-04-01", "2025-05-01"),
    spatial_extent=area,
    show_progress=True,
)

# query data from all collections in the dataset
data = sentinel2_msi.query(
    # omit the collections argument to query all collections
    temporal_extent=("2025-04-01", "2025-05-01"),
    spatial_extent=area,
    show_progress=True,
)
```

```go Go theme={"system"}
startDate := time.Date(2025, 4, 1, 0, 0, 0, 0, time.UTC) 
endDate := time.Date(2025, 5, 1, 0, 0, 0, 0, time.UTC)
timeInterval := query.NewTimeInterval(startDate, endDate)
area := orb.Polygon{  // area roughly covering the state of Colorado
    {{-109.05, 41.00}, {-109.045, 37.0},  {-102.05, 37.0}, {-102.05, 41.00}, {-109.05, 41.00}},
}

collectionA, err := client.Collections.Get(ctx, dataset.ID, "S2A_S2MSI2A")
if err != nil {
    log.Fatalf("Failed to get collection: %v", err)
}

collectionB, err := client.Collections.Get(ctx, dataset.ID, "S2B_S2MSI2A")
if err != nil {
    log.Fatalf("Failed to get collection: %v", err)
}

collectionC, err := client.Collections.Get(ctx, dataset.ID, "S2C_S2MSI2A")
if err != nil {
    log.Fatalf("Failed to get collection: %v", err)
}

// query data from a specific collection
var fromCollection []*v1.Sentinel2Msi
err = client.Datapoints.QueryInto(ctx,
    dataset.ID,
    &fromCollection,
    datasets.WithCollectionIDs(collectionA.ID),
    datasets.WithTemporalExtent(timeInterval),
    datasets.WithSpatialExtent(area),
)
if err != nil {
    log.Fatalf("Failed to query datapoints: %v", err)
}

// query data from a selected set of collections
var datapoints []*v1.Sentinel2Msi
err = client.Datapoints.QueryInto(ctx,
    dataset.ID,
    &datapoints,
    datasets.WithCollectionIDs(collectionA.ID, collectionB.ID, collectionC.ID),
    datasets.WithTemporalExtent(timeInterval),
    datasets.WithSpatialExtent(area),
)
if err != nil {
    log.Fatalf("Failed to query datapoints: %v", err)
}

// query data from all collections in the dataset
var datapointsFromAllCollections []*v1.Sentinel2Msi
err = client.Datapoints.QueryInto(ctx,
    dataset.ID,
    &datapointsFromAllCollections,
    datasets.WithTemporalExtent(timeInterval),
    datasets.WithSpatialExtent(area),
)
if err != nil {
    log.Fatalf("Failed to query datapoints: %v", err)
}
```

Some datasets include assets that point to files in object storage. After selecting one datapoint, use an [asset collection and the storage client](https://docs-old.tilebox.com/datasets/assets-and-storage/read-and-download.md) to read or download those files.

To learn more about how to narrow down query results, see the following pages about filtering by time, geometry, custom
fields, or datapoint ID.

> [card] [Filter by time](https://docs-old.tilebox.com/datasets/query/filter-by-time.md)
>
> Learn how to run queries for datapoints within a given temporal extent.

> [card] [Filter by geometry](https://docs-old.tilebox.com/datasets/query/filter-by-location.md)
>
> Learn how to filter your query results by a certain geographical extent.

> [card] [Filter by custom fields](https://docs-old.tilebox.com/datasets/query/filter-by-fields.md)
>
> Filter datapoints by queryable fields in the dataset schema.

> [card] [Filter by Datapoint ID](https://docs-old.tilebox.com/datasets/query/filter-by-id.md)
>
> Find individual datapoints by their unique ID.

## Automatic pagination

Querying large datasets can result in a large number of data points. For those cases Tilebox
automatically handles pagination for you by sending paginated requests to the server.

> [!TIP]
>
> When using the python SDK in an interactive notebook environment, you can additionally also display a
> progress bar to keep track of the progress of the query by setting the `show_progress` parameter to `True`.

## Skipping data fields

Sometimes, only the ID or timestamp associated with a datapoint is required. In those cases, you can speed up
querying by skipping downloading of all dataset fields except of the `time`, the `id` and the `ingestion_time` by setting the `skip_data` parameter to `True`.

For example, when checking how many datapoints exist in a given time interval, you can use `skip_data=True` to avoid loading the data fields.
This works the same way on both collection-level and dataset-level queries.

```python Python theme={"system"}
interval = ("2023-01-01", "2023-02-01")
data = collection.query(temporal_extent=interval, skip_data=True)
print(f"Found {data.sizes['time']} data points.")
```

```go Go theme={"system"}
startDate := time.Date(2023, time.January, 1, 0, 0, 0, 0, time.UTC)
endDate := time.Date(2023, time.February, 1, 0, 0, 0, 0, time.UTC)
interval := query.NewTimeInterval(startDate, endDate)

var datapoints []*v1.Sentinel1Sar
err = client.Datapoints.QueryInto(ctx,
  dataset.ID,
  &datapoints,
  datasets.WithCollectionIDs(collection.ID),
  datasets.WithTemporalExtent(interval),
  datasets.WithSkipData(),
)
if err != nil {
  log.Fatalf("Failed to query datapoints: %v", err)
}

log.Printf("Queried %d datapoints", len(datapoints))
log.Printf("First datapoint time: %s", datapoints[0].GetTime().AsTime())
```

Output

```plaintext Python theme={"system"}
<xarray.Dataset> Size: 160B
Dimensions:         (time: 1)
Coordinates:
    ingestion_time  (time) datetime64[ns] 8B 2024-08-01T08:53:08.450499
    id              (time) <U36 144B '01910b3c-8552-7671-3345-b902cc0813f3'
  * time            (time) datetime64[ns] 8B 2024-08-01T00:00:01.362000
Data variables:
    *empty*
```

```plaintext Go theme={"system"}
Queried 1 datapoints
First datapoint time: 2024-08-01 00:00:01.362 +0000 UTC
```

## Empty response

Query will not raise an error if no data points are found for the specified query, instead an empty result is returned.

In python, this is an empty `xarray.Dataset` object. In Go, an empty slice of datapoints. To check for an empty response, you can coerce the result to a boolean
or check the length of the slice.

```python Python theme={"system"}
timestamp_with_no_data_points = "1997-02-06 10:21:00:000"
data = collection.query(temporal_extent=timestamp_with_no_data_points)
if not data:
    print("No data points found")
```

```go Go theme={"system"}
timeWithNoDatapoints := query.NewPointInTime(time.Date(1997, time.February, 6, 10, 21, 0, 0, time.UTC))

var datapoints []*v1.Sentinel1Sar
err = client.Datapoints.QueryInto(ctx,
  dataset.ID,
  &datapoints,
  datasets.WithCollectionIDs(collection.ID),
  datasets.WithTemporalExtent(timeWithNoDatapoints),
)
if err != nil {
  log.Fatalf("Failed to query datapoints: %v", err)
}

if len(datapoints) == 0 {
  log.Println("No data points found")
}
```

Output

```plaintext Python theme={"system"}
No data points found
```

```plaintext Go theme={"system"}
No data points found
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.