Get your dream built 10x faster

Replit and Looker Integration: 2026 Guide

We build custom applications 5x faster and cheaper 🚀

Book a Free Consultation
4.9
Clutch rating 🌟
600+
Happy partners
17+
Countries served
190+
Team members
Matt Graham, CEO of Rapid Developers

Book a call with an Expert

Stuck on an error? Book a 30-minute call with an engineer and get a direct fix + next steps. No pressure, no commitment.

Book a free consultation

How to Integrate Replit with Looker

Replit can integrate with Looker through Looker’s official REST (and Admin) APIs. The integration typically means your Replit app either fetches analytics from Looker or sends data/events to Looker via these APIs. You’ll use HTTPS calls (authenticated by Looker API credentials) from your Repl, usually using a language like Node.js or Python. Replit doesn’t have a built-in Looker connector, so the communication is explicit—via API calls. Store your Looker credentials (Client ID and Client Secret) securely in Replit Secrets, authenticate to get an access token from Looker, then use that token in your further requests.

 

How It Works Conceptually

 

Looker exposes an API endpoint where apps can connect to run queries, fetch dashboard tiles, or manage resources programmatically. Replit, being your runtime, becomes a small web service that talks to Looker’s API. You’ll:

  • Get credentials from your Looker Admin page (API3 Credentials).
  • Save those credentials securely in Replit Secrets (not hardcoded in code).
  • Authenticate by calling /api/3.1/login on your Looker instance.
  • Use the returned access token in every subsequent request to Looker’s endpoints.

This lets your Replit service automate insights queries, embed visualizations, or collect analytics results from Looker.

 

Setting up Environment in Replit

 

  • Inside Replit, open the “Secrets” tab on the left sidebar.
  • Add the following variables:
    • LOOKER_BASE_URL → your Looker instance base URL (e.g., https://mycompany.looker.com)
    • LOOKER_CLIENT_ID and LOOKER_CLIENT_SECRET

 

Example Integration (Node.js)

 

import express from "express"
import fetch from "node-fetch"

const app = express()
app.use(express.json())

// Get environment variables
const LOOKER_BASE_URL = process.env.LOOKER_BASE_URL
const LOOKER_CLIENT_ID = process.env.LOOKER_CLIENT_ID
const LOOKER_CLIENT_SECRET = process.env.LOOKER_CLIENT_SECRET

async function getLookerToken() {
  const res = await fetch(`${LOOKER_BASE_URL}/api/3.1/login`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      client_id: LOOKER_CLIENT_ID,
      client_secret: LOOKER_CLIENT_SECRET
    }),
  })

  if (!res.ok) throw new Error("Failed to authenticate with Looker")
  const data = await res.json()
  return data.access_token
}

app.get("/looker-query", async (req, res) => {
  try {
    const token = await getLookerToken()
    // Example: run a Look query
    const lookResponse = await fetch(`${LOOKER_BASE_URL}/api/3.1/looks/1/run/json`, {
      headers: { Authorization: `token ${token}` },
    })
    const results = await lookResponse.json()
    res.json(results)
  } catch (err) {
    res.status(500).send(err.toString())
  }
})

// Bind to 0.0.0.0 so Replit exposes it
app.listen(3000, "0.0.0.0", () => {
  console.log("Server running on port 3000")
})

 

Running the Integration

 

  • Click “Run” in Replit; your server starts on port 3000, exposed by Replit through a generated URL.
  • Visit your Replit URL followed by /looker-query to run the Example Look query.
  • If Looker credentials are correct, you’ll see JSON data returned.

 

Practical Notes

 

  • OAuth/OIDC flow – If you need user-level Looker data access instead of service-level, you’ll implement OAuth 2.0 flow instead of static credentials. Looker supports that, but it’s more advanced.
  • Data handling – If query results are big, don’t store them persistently on Replit; you can stream them directly or pass them to external storage (S3 or database hosted outside Replit).
  • Security – Never print your API credentials. Use Replit Secrets only.
  • Scaling – Keep it small on Replit; for production, run the actual backend externally since Replit restarts sessions often.

 

Verification & Debugging

 

  • Use console.log() on the Replit shell for debugging responses and errors.
  • Inspect the JSON returned by Looker; errors often include “message” and “documentation\_url”.
  • Test your Looker API credentials first using a manual curl command to confirm they work:
curl -X POST "${LOOKER_BASE_URL}/api/3.1/login" \
-H "Content-Type: application/json" \
-d "{\"client_id\":\"$LOOKER_CLIENT_ID\", \"client_secret\":\"$LOOKER_CLIENT_SECRET\"}"

If this succeeds on your terminal, it will also work from Replit.

Use Cases for Integrating Looker and Replit

1

Embed Looker Dashboards in Replit Web Apps

Use Replit to host a small web server that embeds interactive Looker dashboards in real-time. This is useful when you want your internal tool or client portal (built in Replit) to show analytics directly from Looker without exporting data manually. Looker provides Embed URLs generated through its API or admin panel. You can render those inside a secure HTML iframe served from your Replit app.

  • Store your Looker Embed Secret or API credentials in Replit Secrets.
  • Generate a signed embed URL on the backend (using Looker’s Embed SDK or REST API).
  • Serve that URL to your Replit frontend through an HTTP route.
# server.py - Flask app running inside Replit
from flask import Flask, jsonify
import os, requests

app = Flask(__name__)

@app.route("/embed_url")
def get_embed_url():
    # Example: fetch a signed embed URL using Looker API
    headers = {"Authorization": f"token {os.getenv('LOOKER_API_TOKEN')}"}
    r = requests.get("https://yourlookerinstance.com:19999/api/4.0/embed_url/123", headers=headers)
    return jsonify(r.json())

app.run(host="0.0.0.0", port=8000)

2

Embed Looker Dashboards in Replit Web Apps

Replit Workflows can trigger Looker API calls on a schedule or when new data arrives. This lets you automate pulling query results from Looker and sending them elsewhere (for example to a CSV file, Google Sheet, or external webhook). You use Looker’s REST API 4.0 to run queries programmatically and handle results inside your Replit environment.

  • Create a Looker API token from your Looker Admin → Users → API3 Keys.
  • Save it as LOOKER_API_CLIENT_ID and LOOKER_API\_SECRET inside Replit Secrets.
  • Write a script that authenticates with Looker and downloads query results.
# run_query.py - executed via Replit Workflow
import os, requests

auth = requests.post("https://yourlookerinstance.com:19999/api/4.0/login", json={
    "client_id": os.getenv("LOOKER_API_CLIENT_ID"),
    "client_secret": os.getenv("LOOKER_API_SECRET")
})
token = auth.json()['access_token']

headers = {"Authorization": f"token {token}"}
query = {"model": "ecommerce", "view": "orders", "fields": ["orders.count", "orders.created_date"]}
r = requests.post("https://yourlookerinstance.com:19999/api/4.0/queries/run/json",
                  headers=headers, json=query)

print(r.json())  # Use or export this data to another system

3

Webhook-Based Insight Updates for Replit Apps

Replit can act as an endpoint receiver for custom webhooks that notify your app when Looker dashboards or data models update. For instance, a Looker Action or external scheduler can call a Replit-hosted webhook to trigger visual refreshes or downstream notifications. Since Replit exposes your app port publicly, your webhook endpoint can be verified and tested live.

  • Start a Flask or FastAPI server bound to 0.0.0.0 on Replit.
  • Expose a route like /looker\_webhook that handles incoming POST requests.
  • Verify request signatures or tokens before processing to ensure security.
# webhook_server.py
from flask import Flask, request, jsonify
import os

app = Flask(__name__)

@app.route("/looker_webhook", methods=["POST"])
def handle_notification():
    token = request.headers.get("X-Auth-Token")
    if token != os.getenv("LOOKER_WEBHOOK_SECRET"):
        return jsonify({"error": "Unauthorized"}), 403
    payload = request.json
    print("Received Looker update:", payload)
    return jsonify({"status": "ok"})

app.run(host="0.0.0.0", port=8000)

Book Your Free 30‑Minute Migration Call

Speak one‑on‑one with a senior engineer about your no‑code app, migration goals, and budget. In just half an hour you’ll leave with clear, actionable next steps—no strings attached.

Book a Free Consultation

Troubleshooting Looker and Replit Integration

1

Why Looker embed doesn’t load inside Replit webview?

The Looker embed doesn’t load inside Replit’s webview because Looker blocks the inline iframe rendering inside sandboxed or unsecured frames. Replit’s webview runs your app through an internal sandbox domain (like \*.id.repl.co) that isn’t HTTPS-trusted the way Looker expects. Looker’s embed URLs and Content Security Policy (CSP) require a secure top‑level context (with https and no sandbox flags), so the browser prevents the iframe from displaying the dashboard.

 

How to Fix or Work Around

 

  • Open app in new tab: Use the “Open in new tab” button so the page runs under a full HTTPS domain instead of the webview sandbox.
  • Set X-Frame-Options and CSP properly: Looker requires X-Frame-Options: ALLOW-FROM or compatible frame-ancestors rules that include your domain.
  • Use secure embed flow: Always embed Looker dashboards via HTTPS links from your Replit deployment URL, not local preview.
  • Verify embed URL and auth: Sign embed URLs with your Looker embed secret and ensure they are fetched over TLS.

 

// Example Node.js express snippet for signed Looker embed URL
import express from "express"
import crypto from "crypto"

const app = express()
app.get("/embed", (req, res) => {
  const url = "https://your.looker.com/embed/dashboards/1"
  // Use Looker SDK to sign embed URL securely before redirecting
  res.redirect(url)
})
app.listen(3000, "0.0.0.0")

 

2

How to fix Looker API authentication error in Replit Secrets?

Authentication errors with the Looker API on Replit usually mean your environment variables in Secrets are misnamed, formatted incorrectly, or missing. You must ensure the same key names your code expects (like LOOKERSDK_CLIENT_ID and LOOKERSDK_CLIENT_SECRET) exist in Replit Secrets, and that they match the credentials from your Looker Admin panel exactly. Always restart the Repl after updating Secrets since Replit only injects them at startup.

 

Step-by-step Fix

 

  • In Replit, open the Tools → Secrets tab and confirm your Looker environment variables are present and correct.
  • Match names exactly: for example LOOKERSDK_BASE_URL, LOOKERSDK_CLIENT_ID, and LOOKERSDK_CLIENT_SECRET.
  • Check that LOOKERSDK_VERIFY_SSL is true unless you’re testing with a self-signed cert.
  • Restart your Repl for changes to take effect, then test the connection again.

 

from looker_sdk import init40

// The SDK automatically reads credentials from environment vars set in Replit Secrets
sdk = init40()

user = sdk.me()
print(f"Authenticated as: {user.display_name}")

 

This ensures your Looker client authenticates properly without hardcoding credentials and aligns with Replit’s explicit, environment-based runtime model.

3

Why environment variables from Replit Secrets not showing in Looker integration?

Most often, Replit Secrets aren’t visible to your Looker integration because the Looker process isn’t actually reading them from the same runtime environment where you defined them. Replit Secrets only inject environment variables into the Repl's current runtime process (the code you run inside Replit). If Looker connects externally through an API or webhook, those variables must be used by your server code — they aren’t magically passed to Looker itself.

 

Check Environment Scope and Usage

 

  • Confirm variable setup: In Replit, open "Secrets (Environment Variables)" → check variable names match exactly (case-sensitive).
  • Access inside Repl runtime: Use process.env.MY\_SECRET in Node.js to read it. If undefined, restart the Repl to re-inject variables.
  • Verify Looker connection: If Looker fetches data via API, expose the variable from your server (never directly from workspace) so Looker retrieves credentials through your endpoint.

 

// Example: expose variable for Looker API call
import express from "express"
const app = express()

app.get("/config", (req, res) => {
  res.json({ key: process.env.LOOKER_API_KEY })
})

app.listen(3000, "0.0.0.0")  // Must bind on 0.0.0.0 for Replit

 

So, ensure the Looker integration connects to your running Repl endpoint where Replit Secrets exist — not expecting the secrets to appear on Looker’s side automatically.

Book a Free Consultation

Schedule a 30‑Minute No‑Code‑to‑Code Consultation

Grab a quick video call to discuss the fastest, most cost‑efficient path from no‑code to production‑ready code. Zero sales fluff—just practical advice tailored to your project.

Contact us

Common Integration Mistakes: Replit + Looker

Unverified OAuth Redirects

Many try to connect Looker to Replit by just pasting their app’s redirect URL during OAuth setup — but Replit Repls run on temporary URLs that change on each restart. Looker requires a stable OAuth redirect URI to complete the authorization. Without a fixed endpoint, Looker’s callback fails and tokens never arrive. The right way is to use a permanent domain (for example via Replit Deployment or a reverse proxy) and configure that exact redirect URL in Looker. Store client credentials securely in Replit Secrets, never hardcoded in code.

  • Always use environment variables for LOOKER_CLIENT_ID and LOOKER_CLIENT_SECRET.
  • Use Replit Deployments or an external proxy to have a stable redirect domain.
// Load secrets safely
const clientId = process.env.LOOKER_CLIENT_ID
const clientSecret = process.env.LOOKER_CLIENT_SECRET

Missing API Authentication

A common error is calling Looker’s REST or SDK endpoints without running authentication first. Looker APIs require an access token, generated by exchanging credentials through its /login endpoint. Without that token, Replit apps just get 401 errors. Always authenticate before calling any endpoint and refresh tokens when expired.

  • Authenticate on startup or before each API call if token expired.
  • Cache the token in memory; avoid writing tokens to the Replit filesystem for security.
// Get Looker access token
const resp = await fetch("https://yourcompany.looker.com:19999/api/4.0/login", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ client_id: clientId, client_secret: clientSecret })
})
const tokenData = await resp.json()
const accessToken = tokenData.access_token

Ignoring CORS and Local Binding

Looker extensions or webhooks hitting your Replit app often break because the server isn’t bound properly or CORS isn’t configured. On Replit, your Node, Flask, or FastAPI service must bind to 0.0.0.0 and expose the correct port through Replit. Without this, incoming external requests never reach your service. Define safe origins and headers for Looker’s domain if you’re embedding dashboards or webhooks.

  • Bind the app to 0.0.0.0 and the port from process.env.PORT.
  • Enable CORS explicitly for Looker domains.
import express from "express"
import cors from "cors"
const app = express()
app.use(cors({ origin: "https://yourcompany.looker.com" }))
app.listen(process.env.PORT || 3000, "0.0.0.0")

Not Handling Replit’s Persistence Model

Looker integrations often store cached data or temporary tokens in local files, but Replit restarts clear runtime state. Once the Repl sleeps or restarts, the in-memory token or local file disappears, breaking Looker sync. Use external persistence for anything stateful: a managed database or a service like Google Cloud Storage, and re-authenticate safely after any restart.

  • Use external DB (e.g., Postgres, Redis, or Looker-hosted database) for persistent data.
  • On Repl restart, auto-fetch fresh Looker access token.
// Re-initialize token each start since Replit restarts clear memory
if (!accessToken) {
  await getNewAccessToken()
}

Still stuck?
Copy this prompt into ChatGPT and get a clear, personalized explanation.

This prompt helps an AI assistant understand your setup and guide you through the fix step by step, without assuming technical knowledge.

AI AI Prompt


Recognized by the best

Trusted by 600+ businesses globally

From startups to enterprises and everything in between, see for yourself our incredible impact.

RapidDev was an exceptional project management organization and the best development collaborators I've had the pleasure of working with.

They do complex work on extremely fast timelines and effectively manage the testing and pre-launch process to deliver the best possible product. I'm extremely impressed with their execution ability.

Arkady
CPO, Praction
Working with Matt was comparable to having another co-founder on the team, but without the commitment or cost.

He has a strategic mindset and willing to change the scope of the project in real time based on the needs of the client. A true strategic thought partner!

Donald Muir
Co-Founder, Arc
RapidDev are 10/10, excellent communicators - the best I've ever encountered in the tech dev space.

They always go the extra mile, they genuinely care, they respond quickly, they're flexible, adaptable and their enthusiasm is amazing.

Mat Westergreen-Thorne
Co-CEO, Grantify
RapidDev is an excellent developer for custom-code solutions.

We’ve had great success since launching the platform in November 2023. In a few months, we’ve gained over 1,000 new active users. We’ve also secured several dozen bookings on the platform and seen about 70% new user month-over-month growth since the launch.

Emmanuel Brown
Co-Founder, Church Real Estate Marketplace
Matt’s dedication to executing our vision and his commitment to the project deadline were impressive. 

This was such a specific project, and Matt really delivered. We worked with a really fast turnaround, and he always delivered. The site was a perfect prop for us!

Samantha Fekete
Production Manager, Media Production Company
The pSEO strategy executed by RapidDev is clearly driving meaningful results.

Working with RapidDev has delivered measurable, year-over-year growth. Comparing the same period, clicks increased by 129%, impressions grew by 196%, and average position improved by 14.6%. Most importantly, qualified contact form submissions rose 350%, excluding spam.

Appreciation as well to Matt Graham for championing the collaboration!

Michael W. Hammond
Principal Owner, OCD Tech

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We’ll discuss your project and provide a custom quote at no cost.Â