New to Kestra?
Use blueprints to kickstart your first workflows.
Build a complete ETL pipeline in Kestra that downloads JSON from an API, filters fields in Python, and computes average price per brand with DuckDB SQL.
A compact, end-to-end ETL (extract, transform, load) pipeline that demonstrates the core data engineering pattern in Kestra: pull raw JSON from a public API, reshape it in Python, then run analytical SQL on the cleaned data with DuckDB. It solves the classic glue problem of stitching together an HTTP download, a Python transform, and a SQL aggregation as one reproducible, observable workflow instead of three disconnected scripts. This is an ideal first flow for anyone learning how Kestra passes files between tasks and orchestrates a polyglot data pipeline.
extract uses io.kestra.plugin.core.http.Download to fetch the raw products JSON from a public API endpoint and store it in Kestra internal storage.transform runs io.kestra.plugin.scripts.python.Script on a python:3.11-alpine container. It receives the downloaded file through inputFiles, keeps only the columns requested in the columns_to_keep input, and writes a cleaned products.json via outputFiles.query runs io.kestra.plugin.jdbc.duckdb.Queries, loads the DuckDB json extension, reads the cleaned file with read_json_auto, and computes the average price per brand. With fetchType: STORE, the result is persisted as a Kestra output you can preview and download in the UI.inputFiles and outputFiles, no manual paths.columns_to_keep array input to control which fields survive the transform.DuckDB is a powerful in-process analytical engine, but it has no scheduler, no retry logic, and no way to coordinate an upstream API call or a Python step. Kestra wraps the whole pipeline in declarative YAML: add event or schedule triggers, set automatic retries on the flaky network download, capture inputs and outputs for full data lineage, and observe every run in one place. The Python and SQL stages stay focused on logic while Kestra handles dependencies, file passing, and execution state.
extract task can reach the public API.This flow uses public data and requires no secrets. To adapt it to an authenticated source, add credentials with {{ secret('YOUR_SECRET_NAME') }} and configure them in your Kestra secret backend.
columns_to_keep input to select different fields.query task output to preview and download the average price per brand.