Instant REST API for popular SQL databases — without sharing credentials.
Turn any saved SQL query into a partner-ready REST endpoint with per-recipient API keys, monthly byte quotas, and a full audit trail. Static or streaming, JSON or NDJSON or CSV, LZ4 compression on the wire — all of it with no infrastructure to host and no SQL exposed to the recipient.
Ask Nova, get SQL + charts
Meet Nova Database REST APIOne key per partner. No credentials shared.
Build an API AutomationScheduled sync to 6+ platforms
Explore API to SQLQuery APIs with SQL, no code
Explore AI Database MCPClaude, Cursor, ChatGPT & Grok talk to your data
Connect AIQuery Streams is a secure, real-time data integration platform that turns any saved SQL query into a partner-ready REST API endpoint — with per-recipient keys, monthly byte quotas, and a full audit trail. The API Platform lets you share live database data with clients, vendors, and internal teams without ever handing out database credentials, SQL code, or your network topology. Learn more at QueryStreams.com and sign up for free to mint your first shared API in five minutes.
Share live database data as a REST API — without sharing credentials
Most teams ship CSV exports, hand out read-only database accounts, or stand up a custom Express service when a partner needs live data. Each approach has the same problem: the partner ends up holding something they shouldn’t have — an inbox full of stale CSVs, a SQL credential that survives long after the engagement ends, or root access to a service no one actively maintains. The Query Streams API Platform lets you share the capability to run a saved query, not the credentials underneath it. Every recipient gets their own API key, every call is rate-limited and audited, and access can be revoked from the Portal in a single click without rotating a single database password.
Per-recipient API keys
Every recipient gets their own qsapi_* key. Revoke one without touching the others. Rotate without redeploying anything.
Credentials never leave your network
The Network Agent dials out from your environment. The recipient sees a REST endpoint — never your database hostname, password, or SQL.
Read-only by design
The Agent’s read-only enforcer rejects any non-SELECT statement before it reaches the database. There is no “DELETE by accident” path.
Static and streaming response modes
Pick a single buffered body (8 MB / 100k rows default) or a chunked transfer that pushes rows as the Agent produces them (1 GB / 10M rows default).
LZ4-frame + gzip wire compression
Optional LZ4-frame payload mode for SDK consumers (decompress in one line), plus standard Accept-Encoding: gzip on the uncompressed paths.
Postman-style sandbox built in
Test every endpoint inside the Portal before you share it. Tweak query parameters, inspect the JSON, copy the curl — no separate Postman workspace.
CORS + IP allowlists
Pin a recipient’s key to specific IPs or CIDRs, restrict browser origins per endpoint, and stack the standard two-tier rate limits underneath.
OpenAPI 3.1 spec per endpoint
Every endpoint exposes a machine-readable openapi.json. Feed it to Postman, Swagger UI, or an SDK generator like openapi-typescript.
Popular SQL databases supported
The API Platform works with the SQL databases most teams already run. Once your Network Agent is connected, every saved query against a supported database can be promoted to a shared REST endpoint — no per-database setup, no per-database SDK.
Cloud-hosted databases work the same way
The Agent connects equally well to on-premise databases and managed services like AWS RDS, Azure SQL Database, Google Cloud SQL, and Snowflake. For best latency, deploy the Agent in the same region as the database; one Query Streams account can run multiple Agents across regions and clouds.
How it works in three steps
Once your Network Agent and a supported database connector are set up, promoting a saved query to a shared API takes about five minutes:
Save a SQL query
Build the query in the Portal’s Query Builder against any connected database. Add filters, parameters, and a name. Anything you can SELECT is API-able.
Promote it to an API
Open the Install tab. Choose an endpoint type (permanent, expiring, or N-shot call budget), an inner format (JSON, NDJSON, or CSV), a response mode (static or streaming), and whether LZ4 wire compression is allowed. Save.
Invite recipients by email
Enter a partner’s email; they receive a magic-link claim invitation. Recipients without a Query Streams account get a Free-tier org auto-created on claim — their key is issued the second they accept.
Already use Query Streams for Excel or Google Sheets?
Then your Network Agent is already in place and your database is already connected. Promoting an existing saved query to a REST endpoint takes about a minute — you skip steps 1 and most of step 2. The same saved query can power an Excel refresh, a Sheets sidebar, and a partner-facing REST endpoint at the same time.
Pick a response mode: static or streaming
Every endpoint chooses one of two response modes when you create it. The mode controls how the bytes leave our servers; the wire format (JSON, NDJSON, CSV, or LZ4-frame) is chosen independently per call by the recipient.
The default. We collect every row into a single buffered response, set Content-Length, and emit one body. Errors are normal HTTP status codes (200, 400, 413 API_OUTPUT_TOO_LARGE, 503).
- Default caps: 8 MB / 100,000 rows per call
- Platform max: 50 MB / 1,000,000 rows per call
- Best for: dashboards, on-demand lookups, sub-10k-row queries, curl, AI tools that want one JSON blob
We return 200 OK + Transfer-Encoding: chunked as soon as the first row arrives, then push rows down the wire as the Agent produces them. Memory at our edge stays bounded regardless of result size.
- Default caps: 1 GB / 10,000,000 rows per call
- Platform max: 50 GB / 100,000,000 rows per call
- Best for: n8n / Zapier flows, analytics pipelines, bulk exports, anything that benefits from time-to-first-byte
Mid-stream errors on a streaming endpoint can’t be expressed as an HTTP status code (the status was already sent with the first chunk). We surface them as a sentinel last record: {"_error":"...","rows_returned":N} for NDJSON, or # error: ..., rows_returned: N for streaming CSV. Consumer libraries should check the last record before treating the stream as complete.
Pick a wire format: JSON, NDJSON, CSV, or LZ4-frame
Inside the chosen response mode, recipients pick the wire format per call using standard HTTP headers (Accept for the inner format and Accept-Encoding for compression). One endpoint can serve all four formats; the owner can also lock the endpoint to a single format from the Install tab.
A single JSON array. Default for static mode. The universal format for web clients, AI tools, and curl users.
# Python data = requests.get(url, headers=h).json()
Newline-delimited JSON, one row per line. Streaming-only. Parse-as-you-go for pipelines and ETL.
# Python for line in resp.iter_lines(): row = json.loads(line)
RFC 4180 CSV. Works in static (one body) or streaming (header on first chunk). Open it in Excel, pandas, R, or anything that reads CSV.
# pandas
df = pd.read_csv(url, storage_options=h)
The standards-compliant LZ4 frame format (magic 04 22 4D 18). One frame for static; concatenated frames over chunked transfer for streaming. Bills on compressed bytes.
# Python
data = lz4.frame.decompress(resp.content)
For consumers who want maximum interop, plain JSON (or CSV) is enough — everything else is an opt-in. Wire compression (gzip) layers automatically on top of the uncompressed paths via the standard Accept-Encoding header; we never double-compress, so LZ4-frame replaces gzip rather than stacking on top of it.
The four wire combinations at a glance
Response mode and payload compression compose into four leaf paths. The endpoint owner picks the defaults in the Install tab; the recipient can override per call (within what the owner allows). Wire compression (gzip) negotiated via Accept-Encoding layers on top of the two uncompressed rows automatically.
A single buffered application/json (or text/csv) body with Content-Length. The default path. Wire compression (gzip) negotiated automatically.
A single application/x-lz4-frame body containing one standard LZ4 frame (multi-block). Decompress in one line of consumer code.
application/x-ndjson (or streaming text/csv) over Transfer-Encoding: chunked. One row per chunk. Wire compression (gzip) negotiated automatically.
application/x-lz4-frame as a sequence of concatenated standard LZ4 frames over chunked transfer. No QS-invented framing protocol.
| Mode + compression | Wire MIME type | Body shape | Default caps | Bills on | Use case |
|---|---|---|---|---|---|
| static + none | application/json or text/csv |
One buffered body, Content-Length |
8 MB / 100k rows | uncompressed bytes | Dashboards, curl, default |
| static + lz4 | application/x-lz4-frame |
Single LZ4 frame (multi-block) | 8 MB compressed | compressed bytes | SDK consumers, cost-optimised single response |
| stream + none | application/x-ndjson or text/csv |
Chunked transfer, NDJSON per row | 1 GB / 10M rows | uncompressed bytes | n8n, Zapier, analytics pipelines |
| stream + lz4 | application/x-lz4-frame |
Chunked transfer, concatenated LZ4 frames | 1 GB compressed (~5 GB raw) | compressed bytes | Bulk export, power-user SDK, cheapest-and-fastest combo |
Pass filters at call time
Any saved-query parameter the owner exposes can be set by the recipient on each call. GET requests use the querystring; POST requests use a JSON body. The Agent binds parameters as proper prepared-statement values — never as string concatenation — so a recipient cannot break out of a parameter to inject SQL.
The endpoint owner controls which parameters are exposed (in the Install tab’s Parameters sub-tab), which are locked to a fixed value, and what the allowed set of values is. Recipients can only set parameters that the owner exposed; everything else is fixed. Multi-value parameters use repeated keys (?status=paid&status=shipped) on GET and a standard JSON array on POST.
Security posture: CORS, IP allowlists, and rate limits
Beyond per-recipient keys and read-only enforcement, every endpoint gives you four additional locks you can tighten before you share it.
Per-key IP allowlist
Pin a recipient’s key to a single IP, a CIDR range, or a list. Supports both IPv4 and IPv6. A call from outside the allowlist returns 403 IP_NOT_ALLOWED before the SQL is touched.
Per-endpoint CORS allowlist
Tell us which browser origins are allowed to call the endpoint from JavaScript. Set ["https://app.acme.com"] for a single partner, or leave CORS off entirely (the default) for server-to-server-only endpoints.
Two-tier rate limits
A token bucket on the recipient’s key (default 60 requests/min) plus a second bucket on the endpoint itself (default 120/min). A noisy recipient cannot blow up the budget for the well-behaved ones.
Monthly byte quotas
Optional per-endpoint cap on billed bytes per calendar month. When the cap is hit, calls return 429 ENDPOINT_QUOTA_EXHAUSTED until the period resets. A safe blast-radius limit for new partners.
Every endpoint ships with an OpenAPI 3.1 spec
Each endpoint exposes a machine-readable spec at GET /v1/endpoints/{id}/openapi.json. It describes the URL, the method, every parameter (with type, allowed values, default), every response shape per format (JSON, NDJSON, CSV, LZ4-frame), and every error code. Paste it into Postman or Insomnia for a generated request collection, feed it to Swagger UI for interactive docs, or run it through an SDK generator to get a typed client in your language of choice.
Consume it from Power BI, Tableau, and any JSON tool
Because every endpoint returns standard JSON — with CSV and streaming NDJSON alongside it — any tool that can read a REST feed consumes your data directly, with nothing to install on the recipient’s 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 the 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 add-ons for Excel and Google Sheets are the simpler path — Power Query is there when you want the data in the BI model itself.)
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.
Test endpoints in your browser — Postman-style, without leaving the Portal
Before you hand a key to a partner, run the endpoint yourself. The Install tab has a built-in request builder that mirrors what your recipient will see: pick the HTTP method, set query parameters, choose a sample, fire the request, inspect the response. The sandbox uses a short-lived ephemeral key under the hood, so the call goes through the exact same path a recipient’s request would — same auth, same agent dispatch, same compression negotiation, same byte accounting.
Compression-aware billing
The byte counts in your activity ledger are measured at the egress of our API server and follow a simple, predictable rule: if the recipient opted into LZ4-frame payload compression (Accept-Encoding: lz4), the call bills on the compressed bytes that actually went down the wire; if not, the call bills on the uncompressed bytes. Standard HTTP wire compression (gzip) is pure transport optimisation and does not affect billing — that compression happens after we measured the bytes the consumer is asked to “see.”
Note on bytes-on-wire
If a call opts into LZ4-frame compression, the same JSON payload typically bills at roughly 25-40% of its uncompressed size for transactional rows, and 10-20% for analytics workloads with repeated columns — because that is the amount of data your partner’s network actually moved. The in-browser sandbox surfaces both numbers (X-QS-Bytes-Wire and X-QS-Bytes-Raw) so you can see the savings before you share an endpoint. We chose to bill on wire bytes (when LZ4 is opted into) because that is the number that matches both your data-egress costs and the recipient’s bandwidth consumption. Standard HTTP wire compression (gzip) is pure transport optimisation and does not affect billing. Calls that don’t request LZ4 continue to bill on uncompressed bytes, matching how Excel, Sheets, and the MCP Server are billed today.
Decompression on the consumer side is one line per language. Below is the canonical integration code for each environment we ship samples for:
Built for partner data sharing — not internet-scale APIs
The Query Streams API Platform is designed for the use case where you know your recipients: clients, vendors, internal teams, regulators, auditors, board members. Endpoint quotas, monthly byte caps, and per-recipient rate limits all assume tens to thousands of calls per day per recipient. If your use case is a public marketing API that needs to serve millions of anonymous requests per second, you probably want an API gateway like Kong, Apigee, or AWS API Gateway sitting in front of a service you build yourself. The API Platform complements that pattern; it does not replace it.
Frequently Asked Questions
Do I need to open inbound firewall ports to expose my database as an API? +
Can the recipient see my SQL or my database credentials? +
How do I revoke a partner’s API access? +
401 KEY_REVOKED. Other recipients of the same endpoint continue working with their own keys, and you don’t have to rotate the database password.What’s the difference between static and streaming response modes? +
Content-Length, and emits one HTTP body. Default caps are 8 MB / 100k rows; the platform max is 50 MB / 1M rows. Best for dashboards, sub-10k-row queries, and curl users. Streaming mode emits Transfer-Encoding: chunked and pushes rows down the wire as the Agent produces them. Default caps are 1 GB / 10M rows; the platform max is 50 GB / 100M rows. Best for n8n / Zapier flows, analytics pipelines, and bulk exports. You pick the mode per endpoint; the recipient picks the wire format (JSON, NDJSON, CSV, or LZ4-frame) per call.How do I decompress LZ4-frame responses in my code? +
04 22 4D 18), so every mainstream LZ4 library handles it natively. In Python: lz4.frame.decompress(resp.content). In Node.js with lz4js: LZ4.decompressFrame(buffer). In Go with github.com/pierrec/lz4/v4: lz4.NewReader(body). On the CLI: curl ... | lz4 -d -. For streaming endpoints, the response body is a sequence of concatenated LZ4 frames over Transfer-Encoding: chunked — the same frame decoder handles single-frame and concatenated-frame inputs identically when called in a streaming loop.Can I lock an endpoint to specific IP addresses or browser origins? +
403 IP_NOT_ALLOWED before any SQL is run. Separately, each endpoint has an optional CORS origin allowlist — set it to ["https://app.acme.com"] if the endpoint is meant to be called from a specific partner’s frontend, or leave it off entirely (the default) for server-to-server-only endpoints. Both controls are edited from the Install tab and take effect immediately.How is API Platform usage billed? +
Accept-Encoding: lz4), it bills on the compressed wire bytes; if not, it bills on the uncompressed bytes. The same JSON payload over LZ4 typically bills at 25-40% of its uncompressed size for transactional rows and 10-20% for analytics workloads, because that is the amount of data your partner’s network actually moved. The in-browser sandbox surfaces both numbers side by side. Standard HTTP wire compression (gzip) is pure transport optimisation and does not affect billing.What happens if a query tries to write or delete data? +
READONLY_VIOLATION before it ever reaches your database — the Agent’s read-only validator runs in your network and allows only SELECT statements. why every endpoint is read-only by design →Which SQL databases does the API Platform support? +
Can I see what each recipient actually requested? +
How does this compare to building an API myself with Express, FastAPI, or PostgREST? +
Does the API Platform need a separate subscription on top of Query Streams? +
Get Started
Mint your first shared API in five minutes.
Sign up free, install the Network Agent next to your database, save a SQL query, and email a recipient a magic-link claim invitation. Per-recipient keys, audit trail, and compression-aware billing are on from minute one.
Related guides: Share live database data without sharing credentials | Share query results securely | Connector Setup guides | All MCP Server guides
Category: API Platform
Tags: api-platform, rest-api, share-live-data, partner-api, per-recipient-keys, sql-to-api, instant-api, streaming-api, ndjson, lz4-compression, openapi, postgres, mysql, sql-server, snowflake
Meta Description: Instant REST API for popular SQL databases — static or streaming, JSON/NDJSON/CSV/LZ4-frame, per-recipient keys, OpenAPI 3.1, no credentials shared.

