View Categories

How to Expose a DuckDB Database as a Secure REST API

12 min read

DuckDB logo DUCKDB REST API

Turn a DuckDB query into a secure REST API — no httpserver extension, no service to host.

DuckDB is a fast, file-based analytics engine with no server process and no built-in auth. Save a SQL query against your .duckdb file, mint a per-recipient API key, and hand a partner a live JSON endpoint — no httpserver extension to expose, no FastAPI wrapper to build, no database file to ship. Just a governed, read-only DuckDB REST API in minutes.

No server to run Per-recipient keys Read-only enforced Nothing to deploy

Query Streams is a secure, real-time database integration platform that turns any saved DuckDB query into a partner-ready REST API endpoint — with per-recipient keys, read-only enforcement, and a full audit trail. You get a live DuckDB REST API without running a server, installing the httpserver extension, or shipping your database file. Learn more at QueryStreams.com and sign up for free to publish your first DuckDB endpoint in minutes.

Why expose a DuckDB database as a REST API?

DuckDB is brilliant precisely because it has no server — it runs in-process, reads a single .duckdb file (or queries Parquet, CSV, and JSON in place), and crunches analytical workloads at column-store speed on a laptop or a cron box. But the moment someone outside your team needs those numbers — a client wants a live feed, a partner’s app needs to read a rollup, an analyst wants the aggregate in their dashboard — that serverless strength becomes the obstacle. There is no port to connect to and no login to hand out. The usual workarounds all hurt: you email the .duckdb file (now a full copy of your data lives on someone else’s drive), you stand up the community httpserver extension or a FastAPI wrapper (now you own an HTTP service, its auth, and its TLS), or you schedule yet another CSV export. A DuckDB REST API is the clean version — the partner gets a URL and a token, not your file. Query Streams makes it a saved query plus a key.

No server, no open port

DuckDB has no network listener — and you do not add one. The Network Agent reads your .duckdb file locally and dials out; inbound calls ride back down that one outbound connection.

Per-recipient API keys

Every recipient gets their own qsapi_* key. Revoke one without touching the others — no file to claw back, no password to rotate.

Read-only by design

The Agent opens DuckDB read-only and a validator rejects any non-SELECT statement. There is no INSTALL, COPY, or ATTACH path through the API.

Your SQL and file stay private

The recipient sees the endpoint URL, the JSON response, and any filters you exposed — never your SQL, your schema, or the .duckdb file itself.

Nothing to host or patch

No httpserver extension to expose, no FastAPI app, no reverse proxy. The endpoint runs as a managed feature, so there is no deploy pipeline or TLS rotation to own.

Permanent, expiring, or self-destructing

Make an endpoint permanent, set it to expire on a date, or give it a fixed call budget that self-destructs after a set number of requests.

The usual ways to put a REST API on DuckDB — and why they hurt

There are real options here, and each has its place. The catch is that every one of them leaves you owning infrastructure, handing over a full copy of your data, or both. Here is how the common approaches compare to a Query Streams shared endpoint when the goal is simply “let a specific partner read a specific result set.”

Concern httpserver extension (self-hosted) DIY FastAPI + duckdb Ship the .duckdb file Query Streams
Network exposure You run and expose an HTTP server You host a service None — but the data leaves your control Outbound-only Agent — no inbound port
What the recipient holds A URL that runs arbitrary SQL by default A URL into your service A full copy of your entire database A single-purpose key for one query
Data / schema exposure Whole database, all tables Whatever you hand-code Everything, forever One saved query, nothing else
Per-recipient keys + revoke Not built in Build it yourself Impossible once shared Built in
Audit log of every call Add it yourself Add it yourself No visibility at all Built in
You operate / patch / rotate TLS Yes, forever Yes, forever Nothing to run Managed for you
Data stays live Yes Yes Stale the moment you send it Live on every call

Looking to serve DuckDB over HTTP without the httpserver extension?

The community httpserver extension is great for spinning up an ad-hoc query endpoint on a machine you control. But it runs arbitrary SQL and has no concept of per-recipient keys, quotas, or an audit trail — so it is not something you want pointed at a partner. If your goal is to hand a named partner one governed, read-only result set with its own key and no server to run, that is exactly the gap Query Streams fills.

How Query Streams turns a DuckDB query into a REST API

Once the Network Agent is installed next to your DuckDB file and the connector is configured, promoting a saved query to a shared REST endpoint takes about three steps. If you already use Query Streams for Excel, Google Sheets, or the MCP Server, your Agent and connector are already in place — you start at step two.

1

Point the Agent at your DuckDB file

Install the Network Agent on the machine that holds your .duckdb file and add a DuckDB connector. The Agent opens the file read-only and makes an outbound TLS connection to Query Streams — nothing is exposed to the internet.

2

Save a SQL query

Write the SELECT in the Query Builder against your DuckDB connection — aggregations, window functions, and reads across attached Parquet, CSV, or JSON all welcome. Name it and save.

3

Promote it and share a key

Open the Install tab, choose the endpoint type (permanent, expiring, or call-budget) and output format, then invite a recipient by email. They get a magic-link claim and their own qsapi_* key.

One saved query, many surfaces

The same saved DuckDB query can drive an Excel refresh, a Google Sheets sidebar, a Claude or Cursor conversation through the MCP Server, and a partner-facing REST endpoint at the same time. You build the query once; Query Streams handles the surfaces.

No server to run, no file to hand over

The security model is the reason teams reach for this instead of the httpserver extension or a shared file. Your DuckDB file never leaves your machine, and the path to it lives only inside the Agent’s configuration on your network — it is never transmitted to our cloud and never visible to a recipient. DuckDB itself is opened in read-only mode, and a validator on your network rejects any non-SELECT statement with READONLY_VIOLATION before it can execute.

Beyond read-only enforcement, the same outbound-only Agent (HTTPS on port 443, no inbound ports or VPN) backs every endpoint’s per-recipient controls — IP and CORS allowlists, two-tier rate limits, and optional byte quotas you can tighten before you share. how the outbound-only connection and per-recipient guardrails work →

Call your DuckDB REST API

Recipients call the endpoint like any other REST API: a bearer token and a URL. Any saved-query parameter you exposed can be set per call — on the querystring for GET or in a JSON body for POST. The Agent binds those values as proper prepared-statement parameters, never string concatenation, so a recipient cannot break out of a filter to inject SQL.

GET with a filter parameter
# Recipient call against your DuckDB-backed endpoint curl -H “Authorization: Bearer qsapi_K7…ZmQ” \ “https://api.querystreams.com/v1/endpoints/revenue-by-month?year=2026&region=EMEA”

Pick the output format per call with the Accept header (or a ?format= query parameter): JSON for a single array, CSV for spreadsheets and pandas, or, on a streaming endpoint, NDJSON (one JSON row per line) for parse-as-you-go pipelines — handy for the large analytical result sets DuckDB is built to produce. For bandwidth-sensitive consumers, opt into LZ4 payload compression with Accept-Encoding: lz4; uncompressed responses also get standard gzip on the wire automatically. For the full breakdown of static vs streaming modes, the four wire combinations, and OpenAPI 3.1 generation, see the Instant REST API for SQL databases guide.

How usage is billed

The API Platform is part of every Query Streams plan — no separate subscription — and an Accept-Encoding: lz4 call bills on the compressed bytes that actually moved. how API Platform usage is metered →

Plug it into Power BI, Tableau, and anything that reads JSON

DuckDB is an analytics engine, so most of the time its results are headed for a dashboard. Because every endpoint returns standard JSON — with CSV and streaming NDJSON on tap — any tool that can read a REST feed consumes your DuckDB data directly, with nothing to install on their side. Power Query is the easiest bridge into the Microsoft BI stack: in Power BI choose Get Data → From Web, paste the endpoint URL, add your Authorization header, and Power Query parses the JSON into a refreshable table that feeds your data model. (For live data inside a spreadsheet, the native Query Streams Excel add-on is the simpler path — Power Query is there when you want the data in the Power BI model itself.)

Microsoft Power Query logo Power Query Get Data → From Web, paste the URL and bearer token, expand the JSON to a refreshable table
Microsoft Power BI logo Power BI Same Power Query engine — load the endpoint straight into your model and schedule refresh
Tableau logo Tableau Point a Web Data Connector or JSON source at the endpoint for live dashboards
Postman logo Postman Import the OpenAPI 3.1 spec, then send, inspect, and share requests in one click

It also feeds n8n, Qlik, curl, Python (requests or pandas.read_json), Insomnia, Hoppscotch — or any script or workflow that can send an HTTP request and read JSON.

Works with local files and network shares

The Network Agent connects the same way to a local .duckdb file, a database file on a network share, or an in-memory DuckDB — and it serves any query you can run, including ones that read Parquet, CSV, or JSON files your DuckDB instance can reach. For the lowest latency, run the Agent on or near the machine that holds the data. One Query Streams account can run multiple Agents across machines and sites, and a single endpoint behaves identically regardless of which Agent serves it.

More than DuckDB

The same workflow promotes a saved query from PostgreSQL, Microsoft SQL Server, MySQL, MariaDB, SQLite, Microsoft Access, Snowflake, Oracle, or BigQuery to a REST endpoint. DuckDB is simply one of the fastest-growing starting points. Browse the Connector Setup guides for the current list.

Frequently Asked Questions

Do I need to run a server or install the httpserver extension? +
No. DuckDB stays exactly as it is — an in-process, file-based engine. The Network Agent opens your .duckdb file read-only on your own machine and makes an outbound TLS connection to agent.querystreams.com on port 443. There is no httpserver extension to install, no port to open, and no inbound firewall rule to add.
Can the recipient see my SQL or download my .duckdb file? +
Never. The recipient sees the endpoint URL, the response body, and any parameters you exposed as filters. The SQL stays inside Query Streams, and the .duckdb file never leaves your machine — unlike emailing the file, no copy of your data ever lands on the recipient’s drive.
How is this different from the DuckDB httpserver extension? +
The community httpserver extension turns a machine you control into an HTTP endpoint that runs arbitrary SQL — great for quick internal access, but it has no per-recipient keys, no quotas, no audit trail, and you must host and secure it yourself. Query Streams takes the opposite, narrower angle for outbound sharing: one saved query becomes one endpoint, each recipient gets their own revocable key, every call is audited, and there is nothing for you to deploy or patch.
What output formats can the API return? +
JSON (default), CSV, and — on a streaming endpoint — NDJSON, which suits the large analytical result sets DuckDB produces; recipients pick per call with the Accept header or a ?format= parameter. the four wire combinations and LZ4 compression →
Can the query read Parquet, CSV, or JSON files through DuckDB? +
Yes. Anything your saved SELECT can read in DuckDB — a native table, an attached Parquet or CSV file, a JSON document, or a view across several of them — can become an endpoint. The recipient just sees the JSON result; they never know whether it came from a table or a file behind the scenes.
Can an endpoint expire or self-destruct? +
Yes — an endpoint can be permanent, expire on a date, or carry a fixed call budget that stops after a set number of requests, and any recipient’s key can be revoked instantly without affecting the others. endpoint lifetimes and key revocation explained →
Where does the Agent need to run for DuckDB? +
On a machine that can reach your DuckDB file — either the box that holds the local .duckdb file or one with access to the network share it lives on. For the lowest latency, run it as close to the data as possible. One Query Streams account can run multiple Agents across machines and sites, and any of them can serve the same endpoint.
Does the recipient need a Query Streams account? +
No — share to a person by email and they claim a magic-link key (a Free-tier org is auto-created), or issue a service key for unattended machine-to-machine access. per-recipient keys vs service keys →

Get Started

Publish your first DuckDB REST API for free.

Sign up, install the Network Agent next to your DuckDB file, save a SQL query, and email a recipient a magic-link claim. Per-recipient keys, read-only enforcement, and a full audit trail are on from the first call.

Related guides: Instant REST API for SQL databases | Expose PostgreSQL as a REST API | Database REST API platform | Connector Setup guides

Category: API Platform

Tags: duckdb-rest-api, duckdb, duckdb-server, duckdb-api, rest-api, expose-duckdb-as-api, httpserver-alternative, share-duckdb-data, per-recipient-keys, no-code-api, database-rest-api

Meta Description: Turn a DuckDB query into a secure, read-only REST API with per-recipient keys — no httpserver extension, no server, no code.

Updated on June 16, 2026

Powered by BetterDocs