- Python
- Go
Start in a Notebook
Explore the provided Sample Notebooks to begin your journey with Tilebox. These notebooks offer a step-by-step guide to using the API and showcase many features supported by Tilebox Python clients. You can also use these notebooks as a foundation for your own projects.Start on Your Device
If you prefer to work locally, follow these steps to get started.1
Install Packages
Install the Tilebox Python packages.
Copy
Ask AI
uv add tilebox-datasets tilebox-workflows tilebox-storage
For new projects we recommend using uv. More information about installing the Tilebox Python SDKs can be found in the Installation section.
2
Create an API Key
Create an API key by logging into the Tilebox Console, navigating to Account -> API Keys, and clicking the “Create API Key” button.



Copy the API key and keep it somewhere safe. You will need it to authenticate your requests.
3
Query Data
Use the datasets client to query data from a dataset.
Python
Copy
Ask AI
from tilebox.datasets import Client
client = Client(token="YOUR_TILEBOX_API_KEY")
# select a dataset
datasets = client.datasets()
dataset = datasets.open_data.copernicus.sentinel2_msi
# and load data from a collection in a given time range
collection = dataset.collection("S2A_S2MSI1C")
data_january_2022 = collection.query(temporal_extent=("2022-01-01", "2022-02-01"))
4
Run a Workflow
Use the workflows client to create a task and submit it as a job.
Python
Copy
Ask AI
from tilebox.workflows import Client, Task
# Replace with your actual token
client = Client(token="YOUR_TILEBOX_API_KEY")
class HelloWorldTask(Task):
greeting: str = "Hello"
name: str = "World"
def execute(self, context):
print(f"{self.greeting} {self.name}, from the main task!")
context.submit_subtask(HelloSubtask(name=self.name))
class HelloSubtask(Task):
name: str
def execute(self, context):
print(f"Hello from the subtask, {self.name}!")
# Initiate the job
jobs = client.jobs()
jobs.submit("parameterized-hello-world", HelloWorldTask(greeting="Greetings", name="Universe"))
# Run the tasks
runner = client.runner(tasks=[HelloWorldTask, HelloSubtask])
runner.run_all()
5
Explore Further
Review the following guides to learn more about the modules that make up Tilebox:
Start with Examples
Explore the provided Examples to begin your journey with Tilebox. These examples offer a step-by-step guide to using the API and showcase many features supported by Tilebox Go clients. You can also use these examples as a foundation for your own projects.Start on Your Device
If you prefer to work locally, follow these steps to get started.1
Install Packages
Add the Tilebox library in your project.Install tilebox-generate command-line tool on your machine.
It’s used to generate Go structs for Tilebox datasets.
Shell
Copy
Ask AI
go get github.com/tilebox/tilebox-go
Shell
Copy
Ask AI
go install github.com/tilebox/tilebox-generate@latest
2
Create an API Key
Create an API key by logging into the Tilebox Console, navigating to Account -> API Keys, and clicking the “Create API Key” button.



Copy the API key and keep it somewhere safe. You will need it to authenticate your requests.
3
Query Data
Run tilebox-generate in the root directory of your Go project.
It generates the dataset type for Sentinel-2 MSI dataset. It will generate a
./protogen/tilebox/v1/sentinel2_msi.pb.go file.Shell
Copy
Ask AI
tilebox-generate --dataset open_data.copernicus.sentinel2_msi --tilebox-api-key $TILEBOX_API_KEY
4
Query Data
Use the datasets client to query data from a dataset.
Go
Copy
Ask AI
package main
import (
"context"
"log"
"log/slog"
"time"
"github.com/google/uuid"
"github.com/paulmach/orb"
"github.com/paulmach/orb/encoding/wkt"
"github.com/tilebox/tilebox-go/datasets/v1"
"github.com/tilebox/tilebox-go/query"
)
func main() {
ctx := context.Background()
client := datasets.NewClient()
// select a dataset
dataset, err := client.Datasets.Get(ctx, "open_data.copernicus.sentinel2_msi")
if err != nil {
log.Fatalf("Failed to get dataset: %v", err)
}
// select a collection
collection, err := client.Collections.Get(ctx, dataset.ID, "S2A_S2MSI1C")
if err != nil {
log.Fatalf("Failed to get collection: %v", err)
}
// load data from a collection in a given time range and spatial extent
colorado := orb.Polygon{
{{-109.05, 41.00}, {-109.045, 37.0}, {-102.05, 37.0}, {-102.05, 41.00}, {-109.05, 41.00}},
}
startDate := time.Date(2025, time.March, 1, 0, 0, 0, 0, time.UTC)
endDate := time.Date(2025, time.April, 1, 0, 0, 0, 0, time.UTC)
march2025 := query.NewTimeInterval(startDate, endDate)
// You have to use tilebox-generate to generate the dataset type
var datapointsOverColorado []*v1.Sentinel2Msi
err = client.Datapoints.QueryInto(ctx,
[]uuid.UUID{collection.ID}, &datapointsOverColorado,
datasets.WithTemporalExtent(march2025),
datasets.WithSpatialExtent(colorado),
)
if err != nil {
log.Fatalf("Failed to query datapoints: %v", err)
}
slog.Info("Found datapoints over Colorado in March 2025", slog.Int("count", len(datapointsOverColorado)))
slog.Info("First datapoint over Colorado",
slog.String("id", datapointsOverColorado[0].GetId().AsUUID().String()),
slog.Time("event time", datapointsOverColorado[0].GetTime().AsTime()),
slog.Time("ingestion time", datapointsOverColorado[0].GetIngestionTime().AsTime()),
slog.String("geometry", wkt.MarshalString(datapointsOverColorado[0].GetGeometry().AsGeometry())),
slog.String("granule name", datapointsOverColorado[0].GetGranuleName()),
slog.String("processing level", datapointsOverColorado[0].GetProcessingLevel().String()),
slog.String("product type", datapointsOverColorado[0].GetProductType()),
// and so on...
)
}
5
Run a Workflow
Use the workflows client to create a task and submit it as a job.
Go
Copy
Ask AI
package main
import (
"context"
"log/slog"
"github.com/tilebox/tilebox-go/workflows/v1"
)
type HelloTask struct {
Greeting string
Name string
}
func (t *HelloTask) Execute(ctx context.Context) error {
slog.InfoContext(ctx, "Hello from the main task!", slog.String("Greeting", t.Greeting), slog.String("Name", t.Name))
err := workflows.SubmitSubtasks(ctx, &HelloSubtask{Name: t.Name})
if err != nil {
return err
}
return nil
}
type HelloSubtask struct {
Name string
}
func (t *HelloSubtask) Execute(context.Context) error {
slog.Info("Hello from the subtask!", slog.String("Name", t.Name))
return nil
}
func main() {
ctx := context.Background()
// Replace with your actual token
client := workflows.NewClient()
job, err := client.Jobs.Submit(ctx, "hello-world",
[]workflows.Task{
&HelloTask{
Greeting: "Greetings",
Name: "Tilebox",
},
},
)
if err != nil {
slog.ErrorContext(ctx, "Failed to submit job", slog.Any("error", err))
return
}
slog.InfoContext(ctx, "Job submitted", slog.String("job_id", job.ID.String()))
runner, err := client.NewTaskRunner(ctx)
if err != nil {
slog.Error("failed to create task runner", slog.Any("error", err))
return
}
err = runner.RegisterTasks(
&HelloTask{},
&HelloSubtask{},
)
if err != nil {
slog.Error("failed to register task", slog.Any("error", err))
return
}
runner.Run(ctx)
}
6
Explore Further
Review the following guides to learn more about the modules that make up Tilebox: