Pricing

How to Connect Metabase to Google Sheets

MetabaseSaved SearchDateDocumentAmount07/01INV-40214,280.0007/02INV-40221,860.5007/05INV-40239,140.0007/08INV-40242,375.2507/09INV-40256,902.7507/12INV-40263,118.40BrookedABCDateDocumentAmount123456707/01INV-40214,280.0007/02INV-40221,860.5007/05INV-40239,140.0007/08INV-40242,375.2507/09INV-40256,902.7507/12INV-40263,118.40Google SheetsMetabase report
JW
James Whitfield

Export Metabase questions to Google Sheets, including the public link that works with IMPORTDATA and the session tokens that quietly expire on you.

Metabase already holds the queries you care about, so the job is getting a saved question's results into a sheet on a schedule. There is a genuinely no-code route through public links and IMPORTDATA, and an API route for private data. The main thing to get right is authentication: session tokens expire on a timer and take your scheduled report down with them.

An admin enables public sharing under Admin settings → Public sharing. Then, on the question, use the sharing menu to create a public link. Appending .csv to that link returns the results as CSV, which Sheets can read directly:

Sheets formula
=IMPORTDATA("https://metabase.yourcompany.com/public/question/UUID-HERE.csv")

Honest warning: a public link has no authentication at all. Anyone who obtains the URL sees the data, and the URL will end up in browser history, sheet revision history and anyone's clipboard. Use this for aggregate or non-sensitive figures, never for customer records or anything with PII.

Metabase to Google Sheets for free (Apps Script + API)

For private data, create an API key in Admin settings → Authentication → API keys and send it as an x-api-key header. Older Metabase versions without API keys require posting credentials to /api/session to obtain a session token, which expires after about two weeks, so prefer keys where available.

Code.gs
function importMetabaseQuestion() {  const METABASE = "https://metabase.yourcompany.com";  const API_KEY  = "mb_XXXXXXXXXXXX";     // does not expire on a timer  const CARD_ID  = 148;                    // number in the question's URL   // Note: POST, not GET. A GET here returns 404 and looks like a bad ID.  const response = UrlFetchApp.fetch(    METABASE + "/api/card/" + CARD_ID + "/query/csv",    {      method: "post",      headers: { "x-api-key": API_KEY },      muteHttpExceptions: true,    }  );   if (response.getResponseCode() !== 200) {    throw new Error(response.getResponseCode() + ": " + response.getContentText());  }   // The response is raw CSV text, not JSON.  const data = Utilities.parseCsv(response.getContentText());   const ss = SpreadsheetApp.getActiveSpreadsheet();  const sheet = ss.getSheetByName("Metabase") || ss.insertSheet("Metabase");  sheet.clearContents();  if (data.length) {    sheet.getRange(1, 1, data.length, data[0].length).setValues(data);  }}

For ad-hoc SQL rather than a saved question, post to /api/dataset with a query naming the database ID and your native SQL. In most cases keeping the SQL in a Metabase question is better practice, since it stays reviewable and reusable rather than living inside a spreadsheet.

Limits: Apps Script's six-minute cap applies, and slow questions can exceed it before returning. Metabase also applies a download row ceiling, so aggregate in the question rather than exporting very large raw result sets.

The Brooked method

Brooked authenticates with an API key so scheduled reports do not break when a session expires, lists your saved questions to pick from, and supports questions with parameters so one question can serve several filtered imports. Results land as typed columns rather than raw CSV text.

Step 1: Install Brooked

Install Brooked from the Google Workspace Marketplace. Free tier includes 100 imports per month, no credit card required.

Step 2: Connect Metabase

Choose Metabase in Brooked, enter your instance URL and an API key. Brooked lists the collections and questions that key can reach; pick one and import.

Step 3: Schedule the refresh

Set the import to re-run hourly, daily or weekly so the sheet reflects the question's current results without anyone opening Metabase.

BrookedBrooked AI, Metabase
Live
Ask anything about your Metabase data…

Method comparison

MethodCostSetupRefreshTwo-wayBest for
Manual CSV downloadFree1 minManualNoA one-off result set
Public link + IMPORTDATAFree3 minOn sheet recalculationNoNon-sensitive data, no code at all
Apps Script + Metabase APIFree20 to 30 minTime-driven triggerNoPrivate data and parameterised questions
BrookedFree tier · Pro $29/user/mo~3 minScheduled (hourly, daily, weekly)NoScheduled reporting from saved questions

Common use cases

  • Board packs: pull the metrics questions leadership already trusts into a formatted sheet
  • Blended reporting: join a Metabase result against data that only lives in spreadsheets
  • Snapshots: schedule imports to keep history for questions that only show current state
  • Distribution: give stakeholders numbers without provisioning Metabase seats
  • Alerting: run threshold checks in Sheets against a scheduled Metabase import

Troubleshooting common issues

Frequently asked questions

Can I pull a Metabase question into Sheets without writing code?

Yes, if the data is not sensitive. Enable public sharing in Metabase's admin settings, then share the question as a public link and request its CSV form. That URL can go straight into an IMPORTDATA formula in Sheets and refreshes when the sheet recalculates. The important caveat is that a public link is genuinely public: anyone with the URL sees the results, with no login.

Should I use an API key or a session token?

An API key, on any Metabase version that supports them. Session tokens obtained from /api/session expire, by default after two weeks, so a script built on them works fine and then silently starts failing. API keys are created in admin settings and sent in an x-api-key header, and they do not expire on a timer.

How do I export a saved question's results?

Call /api/card/{id}/query/csv, and note it must be a POST rather than a GET, which is a common source of 404s. The response is raw CSV text rather than JSON, so parse it accordingly. The question ID is the number in the question's URL.

Can I run ad-hoc SQL rather than a saved question?

Yes, by posting to /api/dataset with a query object naming the database ID and either native SQL or an MBQL query. Saved questions are usually the better pattern for reporting, because the SQL lives in Metabase where it can be reviewed and reused rather than buried inside a spreadsheet script.

Why does my export have fewer rows than Metabase shows?

Metabase applies different limits to on-screen display and to downloads, with the display limit far lower. Exporting through the CSV endpoint gets the larger download limit rather than the display cap, so if a browser view looked truncated the export usually is not. Very large result sets do still hit a download ceiling, in which case aggregate in SQL rather than exporting raw rows.

Can I write back to Metabase from Sheets?

No, and that is by design. Metabase is a query layer over your databases, not a system of record, so there is nothing meaningful to write back to. If you need to push edits somewhere, connect to the underlying database directly instead.

Connect Metabase to Google Sheets today.

Free tier: 100 imports per month, no credit card required. Or see the full Metabase integration details.

Install Brooked free →

Also in Analytics & BI

More Analytics & BI guides

Analytics & BI

Connect Google Search Console to Google Sheets

Export Search Console data to Google Sheets past the UI's 1,000-row limit, including the anonymised queries that stop your totals from ever adding up.

JW
James Whitfield
Read
Analytics & BI

How to Connect GA4 to Google Sheets

The free official Google add-on (GA4 Reports Builder) with the scheduling step nobody documents, the native Connected Sheets GA4 connector, BigQuery export for unsampled event-level data, plus the sampling and '(other)' aggregation traps that make GA4 numbers in your sheet diverge from the UI.

JW
James Whitfield
Read
Analytics & BI

How to Connect Looker to Google Sheets

All 4 ways to get Looker data into Google Sheets: Connected Sheets, scheduled delivery, API, or a no-code add-on.

JW
James Whitfield
Read

Get your spreadsheet hours back

Brooked sets up in seconds. Your team is querying live data before lunch.

Get started free