The scenario this page covers
You have logged in to your looky instance and you have zero workspaces — nobody has shared one with you, and your operator has not seeded a starter. This page walks you through creating your first workspace from scratch and publishing a tiny dashboard so you can see the loop end to end.
If a colleague has already shared a workspace with you, you do not need this page — you need Sources and Publish to start contributing. looky workspaces from your linked root will tell you which workspaces you actually have access to.
Before you start
This page assumes you have already gone through Access Your Instance — that is, you have:
- An instance URL (the one your operator gave you, or
https://my.looky.studioif you are on the managed deployment) and a workinglooky login <url> <local_root>. - An active billing account set on that linked root (
looky billing listshows it,looky billing use <billing_account_id>selects it). - A local root directory on disk and a billing subdirectory inside it:
<local_root>/<billing_account_id>/. Every workspace you create lives under that path.
If any of those is missing, fix it first — the commands below assume the CLI knows which instance to talk to and which billing account to attach the new workspace to.
Quick sanity check: run looky whoami from <local_root> and confirm it prints the right instance URL and email. Then cd <local_root>/<billing_account_id> — this is where you will run every command on this page.
Create the workspace
- From the billing directory, register the workspace on the server and scaffold the local skeleton in one step:
cd <local_root>/<billing_account_id> looky create <workspace_slug> --name "My Workspace" --description "First build workspace"Set-Location <local_root>\<billing_account_id> looky create <workspace_slug> --name "My Workspace" --description "First build workspace"The CLI calls your instance's API to register the workspace (so it appears in the UI and in
looky workspaces) and then writes the local folder structure under./<workspace_slug>/. You are the workspace owner with write access. - Enter the new folder and confirm the CLI resolves it:
cd <workspace_slug> looky statusSet-Location <workspace_slug> looky statuslooky statusresolves the workspace id as<billing_account_id>/<workspace_slug>and confirms the CLI is talking to the right instance. Do not runlooky validateyet — there are no sources deployed and no content to compile, so the result is not informative. Validate after the "Publish and verify" section below.
Configure your data source
Edit runtime/sources.runtime.yml to point at the warehouse you want to query. The exact shape is documented in Sources; minimal examples follow.
BigQuery — using the public thelook_ecommerce dataset as a playground:
sources:
ecommerce:
type: bigquery
project_id: my-gcp-billing-project
credentials_file: my-workspace-bq.json
datasets:
- bigquery-public-data.thelook_ecommerce
Drop the service-account JSON in secrets/my-workspace-bq.json. See BigQuery Dataset Access for how to mint that file.
Postgres — DSN (libpq URI without user:password@) plus a credentials JSON in secrets/:
sources:
warehouse:
type: postgres
dsn: "postgresql://db.example.com:5432/analytics?sslmode=require"
credentials_file: warehouse.json
Drop the user/password JSON in secrets/warehouse.json:
{"user": "looky_reader", "password": "..."}
MySQL — mysql://host:port/database DSN (no user:password@, no query string) plus a credentials JSON in secrets/:
sources:
shop:
type: mysql
dsn: "mysql://db.example.com:3306/shop"
credentials_file: shop.json
Drop the user/password JSON in secrets/shop.json (same shape as Postgres).
Once the file is in place, push runtime config to the server before any content push:
looky push --settings
This is the only push that uploads runtime/** and secrets/**. Every subsequent looky push ships content only and assumes the settings are already deployed.
Minimal files for first dashboard
content/models/sales.malloy
##! experimental.parameters
source: sales() is ecommerce.table('bigquery-public-data.thelook_ecommerce.order_items') extend {
dimension: product is product_name
measure: sales_amount is sum(sale_price)
}
query: total_sales is sales() -> {
aggregate: sales_amount
}
query: sales_by_product is sales() -> {
group_by: product
aggregate: sales_amount
order_by: sales_amount desc
limit: 10
}
content/visualizations/sales_total_kpi.yml
id: sales_total_kpi
title: Total Sales
query: "models/sales.malloy::total_sales"
type: kpi
mapping:
value: sales_amount
published: true
content/visualizations/sales_by_product_bar.yml
id: sales_by_product_bar
title: Sales by Product
query: "models/sales.malloy::sales_by_product"
type: bar
mapping:
x: product
y: sales_amount
published: true
content/dashboards/sales_overview.yml
id: sales_overview
title: Sales Overview
layout_mode: fluid_grid
items:
- visualization: sales_total_kpi
- visualization: sales_by_product_bar
published: true
Publish and verify
looky validate
looky diff
looky push
looky list visualizations
looky list dashboards
Open your instance URL in a browser (the same one you used in looky login), navigate into the workspace, and confirm the sales_overview dashboard is visible and renders both items.
A green looky push means the server accepted the files — not that the dashboard is correct. Always open the UI and look at it before considering the workspace done.
Expected directory shape
<local_root>/
<billing_account_id>/
<workspace_slug>/
workspace.yml
content/
models/
visualizations/
dashboards/
exports/
runtime/
sources.runtime.yml
secrets/
All CLI workspace commands assume you run from <workspace_slug> root.