View Categories

Power BI REST API: Connect Live SQL Data Without ODBC Drivers

14 min read

POWER BI POWER QUERY M

Point Power BI at a REST API instead of a database driver

Query Streams turns any saved SQL query into an authenticated JSON endpoint, then generates the Power Query M that reads it. Paste one block into the Advanced Editor and the report refreshes from live data.

No ODBC driver No inbound port Key, not credentials One .pq file

Query Streams is a secure, real-time database integration platform that publishes any saved SQL query as an authenticated REST endpoint, then hands you the Power Query M to read it from Power BI. Learn more at QueryStreams.com and sign up for free to build your first endpoint and paste it into a report today.

Why Power BI usually needs a driver, a gateway, or both

The normal way to get a SQL database into Power BI is a native connector or an ODBC driver. That works well when the database sits somewhere Power BI can reach. It gets expensive the moment it does not.

If the database lives on your own network, Power BI cannot reach it directly, so Microsoft’s answer is the on-premises data gateway: a service you install, register, patch, and monitor, holding a credential set for every data source behind it. If the database is an engine Power BI has no first-party connector for, you are installing and version-matching an ODBC driver on every machine that opens the report. And in both cases the report itself holds a connection to the database, which means whoever can edit the dataset is one dialog away from the credentials.

A REST endpoint sidesteps all three problems, because Power BI already knows how to read JSON over HTTPS with no driver at all. The hard part was never Power BI’s side. It was producing a safe, parameterised, authenticated endpoint in front of a database without building an API service yourself. That is the part Query Streams does.

No ODBC driver to install

Power BI reads JSON over HTTPS natively. Nothing to install on the report author’s machine, nothing to version-match.

No inbound firewall rule

The Query Streams Agent dials out from your network. Your database port stays closed to the internet.

A key, not a credential

The report holds an API key scoped to one endpoint. It never holds a database username or password.

Read-only, enforced at the agent

The agent validates every statement before it reaches the database. A report cannot write, drop, or alter anything.

Parameters travel with the file

Every filter your query exposes arrives as a named entry in the M, commented with its type, default, and whether it is required.

Full audit trail

Every refresh is a logged API call with a key, a timestamp, and a row count. You can see which report pulled what, and when.

What the Power Query M export actually contains

Open any endpoint in the Query Streams portal, click ‘Export’, and choose ‘Power Query M (.pq)’ under Data Tools. You get a single let ... in ... expression, written for your endpoint, with your parameters already in it. Here is what a generated file looks like for a GET endpoint with two filters:

monthly-revenue-by-region.pq
// ─────────────────────────────────────────────────────────────
//  Query Streams endpoint: Monthly Revenue by Region
//  Aggregated order totals grouped by sales region.
//
//  HOW TO USE
//    Excel:    Data → Get Data → From Other Sources → Blank Query
//              → Advanced Editor → paste this whole block.
//    Power BI: Home → Transform data → New Source → Blank Query
//              → Advanced Editor → paste this whole block.
//
//  Replace the placeholder API key on line 'ApiKey ='. Tweak
//  any parameter value in the 'Params' record. Run.
// ─────────────────────────────────────────────────────────────

let
    ApiKey  = "qsk_live_replace-me",

    // ── PARAMETERS ──────────────────────────────────────────
    //  Edit values below. Each comment shows the contract
    //  (required vs optional, type, default, description).
    //  'compression=none' is intentional: Power Query M has
    //  no LZ4 decoder, so we ask the API for raw JSON.
    Params  = [
        compression = "none",
        // required, date -- first day of the reporting window
        start_date = "2026-01-01",
        // optional, text, default "all" -- sales region filter
        region = "all"
    ],

    BaseUrl = "https://api.querystreams.com/v1/endpoints/8f2c1a94-...",

    Response = Json.Document(
        Web.Contents(
            BaseUrl,
            [
                Headers = [
                    #"X-API-Key" = ApiKey,
                    #"Accept"    = "application/json"
                ],
                Query   = Params
            ]
        )
    )
in
    Response

// ─────────────────────────────────────────────────────────────
//  NEXT STEPS (in the Power Query Editor)
//
//    1. Click the response preview to inspect the record.
//    2. For tabular results, click into the 'data' field.
//    3. Click 'To Table' then expand the record column to
//       break out the individual row fields.
// ─────────────────────────────────────────────────────────────

Four things in that file are doing more work than they look like they are.

BaseUrl A static string, never built by concatenation. Power BI refuses to schedule a refresh when a URL is assembled from variables, because it cannot verify the destination ahead of time. Keeping the URL literal and putting every parameter in the Query record is what makes the report refreshable in the Power BI Service.
X-API-Key A per-recipient key, not a database login. It is scoped to the endpoints you granted it, carries its own monthly quota, and can be revoked on its own without touching the database or any other report.
Params Your query’s filters, with the contract inline. Each entry is generated from the saved query’s parameter definitions, and the comment above it states whether the parameter is required, its type, its default, and what it does. Names that M cannot use bare, like order-id, come through pre-quoted as #"order-id".
Response Deliberately left as the raw record. The export stops at Json.Document rather than auto-flattening to a table. Endpoints return different shapes, and a generated ‘Expanded’ step would break the moment you pointed the same M at a different endpoint. The trailing comment walks you through the three clicks instead.

Connect Power BI to your REST API in four steps

1

Publish the query

Save a SQL query in Query Streams and turn it into an endpoint. Add filters as parameters if the report needs them.

2

Export the M

Click ‘Export’, then ‘Power Query M (.pq)’. Open the file and replace qsk_live_replace-me with a real API key.

3

Paste it in

In Power BI Desktop: Home, then ‘Transform data’, then ‘New Source’, then ‘Blank Query’, then ‘Advanced Editor’. Paste the whole block.

4

Shape and load

Click into the data field, hit ‘To Table’, expand the record column, then ‘Close & Apply’.

Pro tip: promote ApiKey and any filter you want business users to change into real Power Query parameters (Home, then ‘Manage Parameters’). The report author edits them from a dropdown instead of opening the Advanced Editor, and you can keep one dataset serving several regions or date ranges.

Why the export switches compression off

Query Streams endpoints compress their responses with LZ4 by default, which is why large result sets move quickly to the Excel add-in, the Google Sheets add-on, and application clients. Power Query M has no LZ4 decoder. Handed a compressed body it would read the framed bytes as garbage and fail somewhere unhelpful.

So the generated M always sends compression=none and the API returns plain JSON. It is the one line in the file you should not delete. It is also the reason a very wide result set will feel slower in Power BI than the same query does in the Excel add-in, which does decompress.

Worth knowing before you build on it: because the Power BI path is uncompressed, a refresh moves more bytes over the wire than the same query would through the Excel add-in, and those bytes count toward your plan’s data allowance. For a summary table feeding a dashboard this is irrelevant. For a report pulling hundreds of thousands of raw rows on a schedule, aggregate in SQL before the endpoint rather than in Power Query, and you will move a fraction of the data.

The same file works in Microsoft Excel

Power Query is the same engine in both products, so the exported .pq is not Power BI specific. In Microsoft Excel the path is ‘Data’, then ‘Get Data’, then ‘From Other Sources’, then ‘Blank Query’, then ‘Advanced Editor’ — paste the identical block. The generated file’s header comment lists both routes for exactly this reason.

That said, if Excel is where the data is going, the Query Streams Excel add-in is the better tool. It handles authentication for you, lists your saved queries in a sidebar, exposes filters as real controls, runs several queries into several worksheets at once, and uses the compressed transport. The Power Query M route exists for the cases the add-in does not cover: Power BI itself, locked-down Office deployments where add-ins are blocked, and datasets that need to refresh on a server-side schedule.

Power Query M against the usual Power BI connection routes

What you need Native connector or ODBC Query Streams REST API
Reach a database on a private network On-premises data gateway to install and maintain Agent dials out; nothing to install for Power BI
Connect an engine with no first-party connector Find, license, and version-match an ODBC driver Same JSON endpoint regardless of engine
Keep database credentials out of the report Dataset stores a data source credential Report holds a revocable, scoped API key
Guarantee the report cannot write Depends on the database account you granted Read-only validated at the agent, every call
Give a partner one table, not the schema Views plus per-partner database accounts One endpoint, one key, its own quota
Fold report-side filters back into SQL Query folding pushes filters to the engine Filters are endpoint parameters, set before the call

That last row is a genuine trade, not a marketing hedge. A native connector supports query folding, so a slicer in Power BI can rewrite the SQL that hits the database. A REST endpoint cannot do that: the shape of the query is fixed when you save it, and the report chooses from the parameters you exposed. Design the endpoint to return the grain the report needs, expose the filters that matter as parameters, and the difference stops mattering. Point a report at a raw fact table and expect Power Query to slice it and you will feel it.

Which databases Power BI can reach this way

Because Power BI only ever sees JSON, every engine Query Streams connects to looks identical from the report’s side. That includes Microsoft SQL Server, PostgreSQL, MySQL, MariaDB, Oracle, SQLite, Microsoft Access, Snowflake, BigQuery, and DuckDB, along with hosted variants like Amazon RDS, Azure SQL Database, Google Cloud SQL, Neon, Supabase, and PlanetScale. It also covers the API connectors — Stripe, HubSpot, Shopify, Google Analytics, Google Ads, Google Search Console — which means a Power BI report can read a SaaS platform as if it were a SQL table.

The endpoint is where the difference disappears. Whether the SQL underneath runs against Oracle on a machine in your server room or against a Postgres branch in the cloud, the M in your report is the same nine lines. See the full list on the database integrations page, or read how a saved query becomes an endpoint.

Frequently Asked Questions

Do I need the on-premises data gateway? +
No. The gateway exists so Power BI can reach a data source inside a private network. Query Streams already solves that a different way: the Network Agent runs on your network and dials out, so Power BI only ever talks to a public HTTPS endpoint at api.querystreams.com. From Power BI’s point of view there is no private network involved, which is the same reason it can refresh any web data source without a gateway.
Will scheduled refresh work in the Power BI Service? +
Yes, and the generated M is written specifically so it can. Power BI blocks scheduled refresh on what it calls dynamic data sources — URLs assembled at runtime from variables — because it cannot check the destination in advance. The export keeps BaseUrl as a literal string and passes every parameter through Web.ContentsQuery option, which is the shape the Service accepts. Set the credential for the data source to Anonymous; the API key travels in the X-API-Key header, not in the URL.
Is this DirectQuery or Import? +
Import. A web data source loads its rows into the model when the dataset refreshes, so the report is as current as its last refresh. That is the right mode for the great majority of reporting, but if you need a visual that re-queries the database on every slicer click, a REST endpoint is not the tool — you want a native DirectQuery connector for that.
Why is compression=none in my query, and can I remove it? +
Leave it. Query Streams endpoints return LZ4-compressed bodies by default, and Power Query M has no LZ4 decoder — it would read the compressed bytes as malformed JSON. That single parameter tells the API to send plain JSON instead. It is the one thing in the generated file that will break the query if you delete it.
Can a Power BI report write back to my database? +
No, and not just by convention. The Network Agent validates every statement before it reaches the database and rejects anything that is not a read. An endpoint cannot be pointed at an INSERT, UPDATE, DELETE, or DDL statement, so there is no configuration in which a report could modify data.
How do I share a report with someone outside my company? +
Issue them their own API key rather than sharing yours. Each key is scoped to specific endpoints, carries its own monthly call quota, and appears separately in the audit log, so you can see exactly what each recipient pulled. Revoking one key stops that recipient and leaves every other report working. Nobody in the chain ever receives a database credential or sees the SQL behind the endpoint.
My endpoint takes parameters. How do I change them from the report? +
Every parameter your saved query exposes arrives as a named entry in the Params record, with a comment stating its type, default, and whether it is required. Edit the values there for a fixed report, or promote them to Power Query parameters through ‘Manage Parameters’ so the report author can change them from a dropdown without touching the M. Note that these are set before the call, so they are not the same as a Power BI slicer, which filters rows the model already loaded.
What else can consume the same endpoint? +
Anything that speaks HTTP. Alongside the Power Query M file, the export menu produces an OpenAPI 3.1 specification in JSON or YAML, plus ready-made Postman, Insomnia, and Hoppscotch collections for testing. The same endpoint also backs Airtable, Baserow, SeaTable, Smartsheet, and Anvil integrations. One saved query, one endpoint, many consumers.
Does a large result set slow the refresh down? +
It can, because this path is uncompressed by necessity. The fix is almost always to move the aggregation into the SQL behind the endpoint rather than doing it in Power Query. A dashboard that needs monthly totals by region should call an endpoint that returns monthly totals by region, not one that returns every order line and lets the model group them.

Get Started

Put a live database behind your next Power BI report

Save a query, publish it as an endpoint, export the Power Query M, and paste it into the Advanced Editor. No ODBC driver, no gateway, no database port opened.

Related guides: Instant REST API for SQL Databases | Expose a PostgreSQL Database as a Secure REST API | Expose a SQL Server Database as a Secure REST API | All API Platform guides

Category: RestAPI Platform

Tags: power bi, rest api, power query, power query m, business intelligence, sql

Meta Description: Connect Power BI to any SQL database over a REST API. Generated Power Query M, no ODBC driver.

Updated on August 29, 2026

Powered by BetterDocs