View Categories

How to Expose a SQLite Database as a Secure REST API

13 min read

SQLite logo SQLITE REST API

Turn a SQLite query into a secure REST API — no server, no shared file.

SQLite is the most deployed database on earth — embedded, file-based, no server, no auth. Save a SQL query against your .sqlite file, mint a per-recipient API key, and hand a partner a live JSON endpoint — no database file to ship, no Flask wrapper to build, no Datasette to host. Just a governed, read-only SQLite 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 SQLite query into a partner-ready REST API endpoint — with per-recipient keys, read-only enforcement, and a full audit trail. You get a live SQLite REST API without running a server, shipping your database file, or hosting a publishing tool. Learn more at QueryStreams.com and sign up for free to publish your first SQLite endpoint in minutes.

Why expose a SQLite database as a REST API?

SQLite runs everywhere — inside apps, on shared drives, behind small internal tools, on the edge — precisely because it has no server. It is a single file and a library, nothing to administer. But that strength becomes the wall the moment someone outside the box needs the data: a client wants a live feed, a partner’s app needs to read a slice, an analyst wants a rollup in their dashboard. There is no port to connect to and no login to issue. The usual workarounds all leak something: you email the .sqlite file (a full copy of your data now lives on someone else’s machine and is stale instantly), you stand up Flask or Datasette on a box you have to host and secure, or you schedule yet another CSV export. A SQLite 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

SQLite has no network listener — and you do not add one. The Network Agent reads your .sqlite 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 SQLite read-only and a validator rejects any non-SELECT statement. There is no UPDATE, DELETE, 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 .sqlite file itself.

Nothing to host or patch

No Datasette instance, no Flask 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 SQLite — 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 Ship the .sqlite file Datasette (self-hosted) DIY Flask + sqlite3 Query Streams
Network exposure None — but the data leaves your control You run and expose a web service You host a service Outbound-only Agent — no inbound port
What the recipient holds A full copy of your entire database A URL into your whole database A URL into your service A single-purpose key for one query
Data / schema exposure Everything, forever Whole database, all tables Whatever you hand-code One saved query, nothing else
Per-recipient keys + revoke Impossible once shared Build it yourself Build it yourself Built in
Audit log of every call No visibility at all Add it yourself Add it yourself Built in
You operate / patch / rotate TLS Nothing to run Yes, forever Yes, forever Managed for you
Data stays live Stale the moment you send it Yes Yes Live on every call

Looking for a Datasette alternative for partner sharing?

Datasette is excellent for publishing and exploring a whole SQLite database as a browsable site with a JSON API — on hosting you run and secure. If instead you want to hand a named partner one governed, read-only result set — with its own key, an audit trail, and no server to run — that is exactly the gap Query Streams fills. The two can coexist: Datasette for open data exploration, Query Streams for controlled outbound sharing.

How Query Streams turns a SQLite query into a REST API

Once the Network Agent is installed next to your SQLite 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 SQLite file

Install the Network Agent on the machine that holds your .sqlite (or .db / .sqlite3) file and add a SQLite connector. The Agent opens the file read-only and makes an outbound TLS connection — nothing is exposed to the internet.

2

Save a SQL query

Write the SELECT in the Query Builder against your SQLite connection — JOINs, CTEs, aggregations, and parameters all welcome. Name it and save. Anything you can SELECT can become an endpoint.

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 SQLite 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 emailing the file or standing up a publishing tool. Your SQLite file never leaves its 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. On top of that, every endpoint gives you per-recipient controls you can tighten before you share.

Outbound-only Agent

The Agent dials out on port 443, so there are no inbound ports, VPNs, or tunnels to open. how the outbound-only connection works →

Read-only enforcement

SQLite is opened in read-only mode and a validator runs on your network before any statement executes. Non-SELECT statements are rejected with READONLY_VIOLATION.

IP + CORS allowlists

Pin a recipient’s key to specific IPs or CIDR ranges, and restrict which browser origins may call each endpoint. Off-list calls are refused before any SQL runs.

Rate limits + byte quotas

Two-tier rate limits (per key and per endpoint) plus an optional monthly byte cap keep a noisy or runaway recipient inside a safe blast radius.

Call your SQLite 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 SQLite-backed endpoint curl -H “Authorization: Bearer qsapi_K7…ZmQ” \ “https://api.querystreams.com/v1/endpoints/active-orders?status=open&since=2026-01-01”

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. 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

A call that opts into Accept-Encoding: lz4 bills on the compressed bytes that actually moved; otherwise it bills on the uncompressed bytes, and standard gzip on the wire is transport-only and never affects billing. how the shared byte allowance is metered →

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

Because every endpoint returns standard JSON — with CSV and streaming NDJSON on tap — any tool that can read a REST feed consumes your SQLite 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 on shared drives and embedded files too

It does not matter where your SQLite database lives. The Agent connects the same way to a file on a local disk, a file on a shared network drive, or the database embedded alongside an application or internal tool — whether the extension is .sqlite, .db, or .sqlite3. For the lowest latency, run the Agent on the machine that holds the file; one Query Streams account can run multiple Agents across servers and sites, and a single endpoint behaves identically regardless of which Agent serves it.

More than SQLite

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

Frequently Asked Questions

Do I need to run a server or open a port for SQLite? +
No — SQLite stays an embedded, file-based engine and the Network Agent reads your .sqlite file locally over a single outbound port-443 connection, so there is no server, port, or inbound firewall rule. why no inbound port is ever opened →
Can the recipient see my SQL or download my .sqlite 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 .sqlite 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 Datasette? +
Datasette publishes an entire SQLite database as a browsable web app with a JSON API, on hosting you run and secure — great for open data exploration. 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. Many teams use both for different jobs.
Is it safe to point this at a live application’s SQLite file? +
Yes. The Agent opens the database read-only, so it cannot modify your data, and SQLite supports concurrent readers alongside your application’s writes. For very write-heavy databases you can also point the Agent at a copy or a WAL-mode read replica — but for most internal SQLite databases, read-only access to the live file is perfectly safe.
What output formats can the API return? +
JSON (the default array), CSV, and — on a streaming endpoint — NDJSON, chosen per call with the Accept header or a ?format= parameter, with optional LZ4 payload compression. the output formats and wire modes explained →
Can an endpoint expire or self-destruct? +
Yes — an endpoint can be permanent, expire on a date, or carry a fixed call budget, and any recipient’s key can be revoked instantly without affecting the others. endpoint lifetimes and per-key controls →
Does the recipient need a Query Streams account? +
Sharing by email gives the recipient a magic-link claim and an auto-created Free-tier org keyed to them, while a service key covers unattended machine-to-machine access without a per-person claim. recipient claims vs service keys →

Get Started

Publish your first SQLite REST API for free.

Sign up, install the Network Agent next to your SQLite 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 DuckDB as a REST API | Database REST API platform | Connector Setup guides

Category: API Platform

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

Meta Description: Turn a SQLite query into a secure, read-only REST API with per-recipient keys — no server, no shared file, no code.

Updated on June 16, 2026

Powered by BetterDocs