New to Kestra?
Use blueprints to kickstart your first workflows.
Chain dlt ingestion and DuckDB SQL in one Kestra execution. The load produces a DuckDB file, SQL aggregates it via internal storage, Discord gets the KPI.
Ingestion that nobody queries is just storage costs. This blueprint chains the two halves in one execution: io.kestra.plugin.dlt.CLI runs a pipeline script that lands a REST API into a DuckDB file, the file travels through Kestra's internal storage to io.kestra.plugin.jdbc.duckdb.Query, which computes completion KPIs with plain SQL, and Discord receives the numbers seconds after the data lands. No warehouse server, no handoff between two schedulers, no dashboard polling a table that might be mid-load.
load_events (io.kestra.plugin.dlt.CLI) receives the pipeline script through inputFiles and executes it with commands. dlt writes analytics.duckdb in the working directory (with DLT_DATA_DIR keeping pipeline state there too, so every run is self-contained), and outputFiles uploads it to Kestra's internal storage.aggregate (io.kestra.plugin.jdbc.duckdb.Query) opens that file through its databaseUri property, so the SQL queries exactly the file this execution produced, never a half-loaded shared database.fetchType: FETCH_ONE exposes the KPI row as outputs.aggregate.row.*, which publish_kpi interpolates into a Discord message.errors block covers the chain; the execution view shows precisely which half failed.dlt.CLI pattern with inputFiles and outputFiles, ready for repos of pipeline scripts synced from Git.The chain is the point: dlt does not schedule SQL, DuckDB does not fetch APIs, and Discord knows nothing about either. Kestra sequences the three with typed file passing through internal storage, retries per task, and a single execution history entry that answers what ran, what it computed, and who was told. Swapping any link, another source, Postgres instead of a DuckDB file, Slack instead of Discord, changes one task, not the architecture.
env from secrets.DISCORD_WEBHOOK_URL: Discord incoming webhook URL.DISCORD_WEBHOOK_URL secret to your Kestra namespace.daily trigger.namespaceFiles instead of inline inputFiles.fetchType: STORE and feed it to further tasks, or into the dlt freshness monitor blueprint's warehouse.