gptsheet Documentation
BYOK LLM toolkit for Google Sheets and Excel. Pay once. Bring your own API key. Your data and keys never touch our servers.
Welcome
gptsheet adds AI to your spreadsheets through three surfaces:
cell formulas like =AI and =AI_CLASSIFY,
a sidebar with batch tools and an API fetcher, and a
chat agent (Premium) that can read and edit your sheet conversationally.
There are two plans:
| Plan | Price | Includes |
|---|---|---|
| Basic | $69 lifetime | All 13 core formulas, OpenAI + Anthropic, sidebar tools, 1 year of updates |
| Premium | $99 lifetime | Everything in Basic + chat agent + =AI_VISION + =AI_WEB + =AI_IMAGE + all providers + lifetime updates |
Install
Google Sheets
- Open the Google Workspace Marketplace listing for gptsheet.
- Click Install and pick the Google account you want to use.
- Open any sheet → Extensions → gptsheet → Open sidebar.
Microsoft Excel
- Open the Microsoft AppSource listing for gptsheet.
- Click Get it now and sign in with the Microsoft account you want to use.
- Open Excel → Home → My Add-ins → gptsheet.
One license covers both platforms.
Activate your license
After purchase you'll get an email with your license key, formatted like GS-XXXX-XXXX-XXXX-XXXX.
- Open the sidebar → click the ≡ menu (top-left).
- Tap License.
- Paste the key and click Activate.
Your license binds to the Google or Microsoft account that activates it. You can sign in to that account on multiple devices, but the license itself can't be shared across users.
Set up API keys
gptsheet is BYOK — you bring your own keys from each LLM provider you want to use.
Keys are stored only in your browser's localStorage for sidebar tools, and in your
sheet's PropertiesService for cell formulas. Our server never sees them.
- Open the sidebar → ≡ menu → API keys.
- Click the ✎ pencil next to a provider (OpenAI, Anthropic, Gemini).
- Paste your key and click Save.
The first provider you save becomes the default — used by sidebar tools and as the default for cell formulas. You can change the default anytime by clicking Make default on another configured provider.
See the Providers section below for where to get each key.
Custom Prompt
The escape hatch for "do X to every row in this column" when no named formula fits.
- Select a range in the sheet (e.g.
A2:A20). - Sidebar → Prompt tab.
- Type an instruction. Click Run on selection.
The sidebar reads your selection's first column, calls the LLM once per row, and writes results into the column immediately to the right.
Example: select A2:A20 filled with company names →
type "Find each company's industry, one word" → results land in B2:B20.
Bulk Apply
Run a named formula across hundreds or thousands of rows with progress + stop.
- Sidebar → Bulk tab.
- Pick a formula from the dropdown (
=AI_CLASSIFY,=AI_TRANSLATE, etc.). - Fill in the formula-specific parameters (categories, target language, etc.).
- Set the input range and output column (auto-populated when you click Use selection).
- Click Run. Watch the progress bar. Click Stop anytime — partial results are preserved.
Bulk Apply runs in your browser, bypassing Apps Script's 6-minute execution cap and its UrlFetchApp daily quota. Use it for large batches (500+ rows).
API Fetcher
Paste a REST URL → JSON data appears in your sheet. Auth tokens stay in your browser; gptsheet never sees them.
- Click into an empty area of your sheet (the data will land at the active cell).
- Sidebar → Fetch tab.
- Paste the URL.
- Optionally paste JSON headers (e.g.
{"Authorization": "Bearer ..."}). - Click Fetch to sheet.
The fetcher handles common JSON shapes: array-of-objects (becomes a table with headers), array-of-primitives (single column), or a single object (two columns: key, value).
Cell formulas overview
Each formula calls an LLM from Google Apps Script's UrlFetchApp using your saved
provider key. You can use them like any other Sheets formula — composing with ARRAYFORMULA,
fill-down, conditional refs, etc.
Common parameters
Every formula accepts these optional trailing arguments:
| Argument | Default | Notes |
|---|---|---|
temperature | 0.3 | 0-2, controls randomness |
model | your saved default | Override per-call, e.g. "gpt-4o" |
=AI Basic
Generic LLM prompt that returns a single value.
=AI("Capital of France") → Paris
=AI("Capital of " & A2) → Tokyo (when A2 is "Japan")
=AI_LIST / =AI_HLIST Basic
Returns a list — one item per cell. AI_LIST fills vertically; AI_HLIST fills horizontally.
=AI_LIST("5 marketing channels for SaaS")
=AI_TABLE Basic
Returns a 2D table with headers in the first row.
=AI_TABLE("Top 3 EV makers", "brand,model,price")
=AI_CLASSIFY Basic
Picks one category from a list. Deterministic, taggable.
=AI_CLASSIFY(A2, "positive, negative, neutral")
=AI_CLASSIFY(A2, "enterprise, smb, mid-market", "Use company size as a hint")
=AI_EXTRACT Basic
Pulls specific elements out of messy text. Returns comma-separated values.
=AI_EXTRACT(A2, "phone numbers")
=AI_EXTRACT(A2, "email addresses")
=AI_EXTRACT(A2, "dates in ISO format")
=AI_TRANSLATE Basic
Translates text. Returns only the translation.
=AI_TRANSLATE(A2, "Japanese")
=AI_TRANSLATE(A2, "Japanese", , "Keep brand names in English")
=AI_LANG Basic
Detect the language of a text. Returns the language name in English.
=AI_LANG("Bonjour le monde") → French
=AI_LANG(A2) → e.g. Japanese, Spanish, Arabic
=AI_EDIT Basic
Edits text — fix grammar, change tone, rewrite for an audience.
=AI_EDIT(A2) → fixes grammar/spelling by default
=AI_EDIT(A2, "make it more concise")
=AI_EDIT(A2, "rewrite for a 5th grader")
=AI_FORMAT Basic
Standardize dates, addresses, names, currencies — without writing regex.
=AI_FORMAT(A2, "ISO date")
=AI_FORMAT(A2, "USD with 2 decimals")
=AI_FORMAT(A2, "First Last")
=AI_TAG Basic
Apply tags from your taxonomy, or auto-suggest tags.
=AI_TAG(A2, "urgent, bug, feature, docs")
=AI_TAG(A2, , , 3) → auto-suggest 3 tags
=AI_SPLIT / =AI_HSPLIT Basic
Semantic split — by sentences, paragraphs, sections, etc. Returns one piece per cell (vertical or horizontal).
=AI_SPLIT(A2, "sentences")
=AI_SPLIT(A2, "paragraphs")
=AI_MATCH Basic
Semantic match between two ranges — VLOOKUP that understands meaning. Uses OpenAI embeddings under the hood.
=AI_MATCH(A2:A100, B2:B500)
=AI_MATCH(A2:A100, B2:B500, 0.7, TRUE) → with confidence score in adjacent column
Embeddings aren't supported by Anthropic or Gemini's chat APIs, so =AI_MATCH always uses OpenAI regardless of your default provider.
=AI_CREATE_PROMPT Basic
Helper that concatenates cells and ranges into a single prompt string. Useful for building prompts from sheet data.
=AI(AI_CREATE_PROMPT("Topic:", A2, "Audience:", B2, "Write a tweet."))
=AI_VISION Premium
Analyze an image given its URL — caption, classify, extract text, etc.
=AI_VISION("Describe in one sentence", A2)
=AI_VISION("Extract any text", A2, TRUE)
Uses OpenAI's gpt-4o-mini by default (vision-capable). Pass the image URL in column A and the prompt as the first argument.
=AI_WEB Premium
Web-grounded answer with citations — uses OpenAI's Responses API with the web_search_preview tool.
=AI_WEB("AAPL closing price today")
=AI_WEB("Latest stable Node.js version. Just the number.")
=AI_IMAGE Premium
Generate an image and return a URL. Wrap with =IMAGE(...) to render in a cell.
=IMAGE(AI_IMAGE("a green apple on white background"))
=IMAGE(AI_IMAGE("photo of a sunset", "", "gemini-2.5-flash-image"))
Defaults to OpenAI dall-e-3. Pass gemini-2.5-flash-image or imagen-3.0-generate-002 as the third arg to route through Gemini instead (more permissive rate limits).
Agent overview Premium
A conversational agent that reads your sheet, plans, calls tools, and writes results. Multi-step, context-aware, and editable.
Open the sidebar → Agent tab. Your current cell selection is auto-attached as context — the agent sees what data you're working with before you even ask.
Example prompts:
- "For each row in A2:A20, find the company's industry and write it to column B"
- "Create a bar chart from this data showing revenue by product"
- "What stands out in this data?"
- "Generate an image of a logo for a fintech startup and put it at E5"
Agent tools
The agent has 7 tools it can call:
| Tool | What it does |
|---|---|
get_selection | Read the user's currently selected range. |
read_range | Read values from a specific A1 range. |
write_range | Write a 2D array of values to an A1 range. |
get_sheet_info | Get sheet metadata (name, last row/col, active range). |
create_chart | Insert a native Sheets chart (COLUMN, BAR, LINE, AREA, PIE, SCATTER). |
insert_formula | Insert a live formula at the active cell. |
create_image | Generate an image and embed it as a native image object in the sheet. |
The agent picks the appropriate tool based on the request — you don't need to mention tool names. Use the model picker in the composer to switch between providers for that conversation.
Example tasks
Lead qualification
"For each company in A2:A50, look up the industry and employee count. Write industry to B, count to C. Then score each as 'enterprise', 'mid-market', or 'smb' in column D based on count."
Data viz from selection
"Compare these regions visually." (with A1:B5 selected: Region, Revenue)
Formula composition
"Compute the running average of column B and put it in column C." (uses insert_formula)
BYOK explained
BYOK = Bring Your Own Key. You pay LLM providers directly at their API price. gptsheet is the software layer; the actual LLM bill goes to OpenAI, Anthropic, or Google.
For a typical user running ~1,000 cells through gpt-4o-mini per month, the LLM bill is about $1–3/month. There's no markup or middleman.
| Provider | Where keys are stored | When it's called |
|---|---|---|
| OpenAI / Anthropic / Gemini | Your browser localStorage (for sidebar tools) | Sidebar tools call provider directly from your browser |
| Same keys | Apps Script PropertiesService (synced on save) | Cell formulas call provider via UrlFetchApp from your sheet's Apps Script runtime |
In neither case does the key (or your prompts/data) pass through gptsheet's servers.
OpenAI
Get a key from platform.openai.com/api-keys.
Supported features (via OpenAI key):
- All chat formulas (
=AI,=AI_CLASSIFY, etc.) — usesgpt-4o-miniby default =AI_VISION— usesgpt-4o-mini(vision-capable)=AI_WEB— uses the Responses API withweb_search_previewtool=AI_IMAGE— usesdall-e-3by default=AI_MATCH— usestext-embedding-3-small
New OpenAI accounts can hit Cloudflare rate limits (HTTP 429) on DALL·E 3 image generation. Use =AI_IMAGE(..., "gemini-2.5-flash-image") or upgrade to a higher tier in your OpenAI dashboard.
Anthropic
Get a key from console.anthropic.com/settings/keys.
Supported features (via Anthropic key):
- All chat formulas — uses
claude-haiku-4-5by default - Sidebar agent — full tool-use support via Anthropic's tool-use API
Not yet supported via Anthropic key alone: =AI_VISION (uses OpenAI), =AI_WEB, =AI_IMAGE, =AI_MATCH. These always use OpenAI keys.
Gemini
Get a key from aistudio.google.com/app/apikey. Free tier is generous (15 requests/min).
Supported features (via Gemini key):
- All chat formulas — uses
gemini-2.0-flashby default - Sidebar agent — full tool-use via Gemini's
functionDeclarations =AI_IMAGEwithgemini-2.5-flash-imageorimagen-*models
Gemini's image-gen rate limits are far more permissive than OpenAI's DALL·E. If you generate images frequently, use a Gemini model.
Connectors — overview & setup model
Connectors let the Chat Agent (and direct Run-now buttons in the sidebar) pull data from your apps + databases into Sheets. Each one is configured once in Menu → Connectors; auth lives in your browser's localStorage and is never sent to our servers — only to the upstream provider (Stripe, Notion, GA4, etc.).
Connectors fall into three auth families:
- API token — paste a key from the provider's dashboard. Used by Stripe, Notion, Airtable, PostHog, Amplitude, Ghost.
- Google sign-in (one click) — used by GA4, Search Console, YouTube Insights, Google Ads. No JSON to paste, no service account to create — gptsheet uses your existing Google identity (the one you're signed into Sheets with) via Apps Script's built-in OAuth.
- Direct database — host + credentials for direct SQL access. Used by MySQL, MS SQL Server, Postgres, DynamoDB. Supabase uses its PostgREST gateway + service_role key (no direct JDBC needed).
For the Google sign-in connectors, gptsheet has no OAuth client of its own — Google's tokens are managed by Apps Script's runtime and never accessible to our code or our servers. This is structurally stronger than the service-account model we previously used.
Stripe
Connect Stripe to pull customers, subscriptions, charges, invoices, and balance transactions. The agent can answer "what's my MRR this month?" or "list churned customers last week."
Setup
- Stripe Dashboard → Developers → API keys → Create restricted key.
- Give it read-only permissions for Customers, Subscriptions, Charges, Invoices, Balance.
- Copy the key (starts with
rk_live_orrk_test_). - In gptsheet → Menu → Connectors → Stripe → paste the key → Connect.
Google Analytics (GA4)
Pull GA4 sessions, conversions, channels, top pages.
Setup
- Make sure the Google account you're signed into Sheets with already has at least Viewer access to the GA4 property you want to query. (If not, ask your GA4 admin to add you under GA4 → Admin → Property Access Management → Add user.)
- In gptsheet → Menu → Connectors → Google Analytics → click Connect.
- If this is the first Google connector you've used, Google will prompt you to authorize gptsheet to view your Analytics data. Click Allow. (This is a one-time consent — it covers GA4, GSC, YouTube Insights, and Google Ads together.)
- The Property dropdown auto-populates with every GA4 property your Google account can see. Pick one → Save changes.
- Done. Run any GA4 action (List sessions, Conversion overview, Custom report, etc.).
Want to query multiple GA4 properties? Click "+ Add another account" and pick a different property. Each saved account binds to one property; you can have as many as you want.
Google Search Console
Top queries, top pages, country breakdowns.
Setup
- Make sure the Google account you're signed into Sheets with has access to the Search Console property. (If not, ask the SC admin: Settings → Users and permissions → Add user at search.google.com/search-console.)
- In gptsheet → Menu → Connectors → Google Search Console → click Connect.
- Approve the Google consent screen if prompted (one-time, shared with the other Google connectors).
- The Site dropdown auto-populates with every Search Console property your Google account can access. Pick one — for domain properties this looks like
sc-domain:example.com, for URL-prefix properties likehttps://www.example.com/. Save changes. - Done. Run actions: List queries, Top pages, Country breakdown, Custom report.
YouTube Insights
Channel + video performance via the YouTube Analytics API.
Setup
- Make sure the Google account you're signed into Sheets with owns (or manages) the YouTube channel you want to query.
- In gptsheet → Menu → Connectors → YouTube Insights → click Connect.
- Approve the Google consent screen if prompted.
- Find your Channel ID: YouTube Studio → Settings → Channel → Advanced settings. It's a 24-character string starting with
UC. - Paste the Channel ID → Save changes. Done.
YouTube Analytics only supports channels owned or managed by the signed-in Google account — there's no "grant access" model like GA4. If you don't see data, double-check that the signed-in account has channel access in YouTube Studio.
Google Ads
Campaigns, keywords, spend.
Setup
- The Google account you're signed into Sheets with needs at least Read-only access to the Google Ads account you want to query. (Add via Google Ads → Tools → Account access & security → Users.)
- Get a Developer Token: Google Ads UI → Tools → API Center → Apply for a developer token. (Free, but takes Google 1–2 business days to approve.)
- Find your Customer ID (10-digit number, top-right of the Ads UI — paste without hyphens).
- In gptsheet → Menu → Connectors → Google Ads → click Connect.
- Approve the Google consent screen if prompted.
- Paste Customer ID + Developer Token → Save changes. If you're calling from a manager (MCC) account, also fill
login_customer_id.
The Developer Token is unrelated to OAuth — it's a Google Ads API gate that every API caller needs. Your token applies to your Google account, not to gptsheet.
Meta Ads
- Get your Ad account ID (starts with
act_) from Meta Business Suite → Ads Manager. - Generate a long-lived Marketing API token: Business Suite → Settings → System Users → Add → grant Marketing API access on the ad account → Generate Token.
- Paste both → Connect.
LinkedIn Ads
- Apply for LinkedIn Marketing API access at linkedin.com/developers. Requires manual approval.
- Once approved, complete the 3-legged OAuth flow with scope
r_ads_reporting. - Find your numeric Ad account ID in Campaign Manager.
- Paste both → Connect.
Meta Graph API setup (for Facebook + Instagram Insights)
Both Facebook Insights and Instagram Insights use Meta's Graph API. The auth model is the same: a Meta developer app + a long-lived access token. Set this up once and you can use it for both connectors.
Step 1 — Create a Meta developer app (one-time, 3 min)
- Go to developers.facebook.com/apps.
- Click Create App → Use case: Other → Type: Business.
- Name it anything (
gptsheet-personalworks). Click Create. - In the app dashboard, note the App ID (top of page) and find App Secret under Settings → Basic (click "Show"). You'll need both in Step 3.
Step 2 — Get a short-lived access token (1 min)
- Open Graph API Explorer.
- Top-right Meta App dropdown → select the app you just created.
- Click Get Token → Get User Access Token.
- Tick these permissions (for both FB + IG support):
pages_show_list,pages_read_engagement,pages_read_user_content,instagram_basic,instagram_manage_insights. - Click Generate Access Token → log in → approve. The token appears in the text box.
This token expires in about 1 hour. Convert it to a long-lived one in Step 3 before using it in gptsheet.
Step 3 — Convert to a long-lived token (60-day validity)
Paste this URL into your browser (replace the three values):
https://graph.facebook.com/v19.0/oauth/access_token? grant_type=fb_exchange_token &client_id=YOUR_APP_ID &client_secret=YOUR_APP_SECRET &fb_exchange_token=YOUR_SHORT_LIVED_TOKEN
(Strip the line breaks; that's one URL on one line.) You'll get JSON back with a new access_token — this one lasts 60 days.
Step 4 (optional) — Get a never-expiring Page Access Token
For scheduled imports that auto-refresh, you want a token that never expires. The Page Access Token (derived from the long-lived user token above) never expires:
https://graph.facebook.com/v19.0/me/accounts?access_token=YOUR_LONG_LIVED_USER_TOKEN
Response is a list of Pages you manage. Copy the access_token field from the Page you want — that's your never-expiring token. Use it for both FB + IG connectors.
Facebook Page Insights
Page-level impressions, reach, engagement, fan count + growth, post performance.
Setup
- Complete the Meta Graph API setup above.
- Get your Page ID from the Facebook Page → About → Page transparency → Page ID. (Or use Graph API Explorer:
GET /me/accountsreturns every Page you manage with its ID.) - In gptsheet → Menu → Connectors → Facebook Insights:
- Page ID: the 15-digit number from above.
- Access token: the long-lived user token (Step 3) or never-expiring Page token (Step 4).
- Click Connect.
Available actions
- Page details — name, category, fan count, talking about count
- Recent posts — last 100 posts with reach, engagement, reactions, shares
- Post insights — per-post detailed metrics by post ID
- Page insights (date range) — daily impressions, reach, engaged users, page views
- Fan demographics — by country, city, locale, gender+age (requires ≥100 fans)
Instagram Insights
Business-account level + per-post + per-reel metrics. Audience demographics. Hashtag tracking.
Prerequisites
- Your Instagram must be a Business or Creator account, not Personal. Switch in IG app → Settings → Account → Switch to Professional Account → Business.
- Your IG account must be linked to a Facebook Page. IG app → Settings → Account → Linked Accounts → Facebook → connect the Page. (Create a Page first at facebook.com/pages/create if you don't have one.)
Setup
- Complete the Meta Graph API setup above. (Same app + token works for both FB and IG.)
- In Graph API Explorer with your token loaded, run:
GET /me/accounts?fields=instagram_business_account,name
The response lists every Page you manage; each one has aninstagram_business_account.idfield. Copy the17841...number (15+ digits) for the IG account you want. - In gptsheet → Menu → Connectors → Instagram Insights:
- IG Business account ID: the
17841...number. - Access token: the long-lived user token (Step 3) or never-expiring Page token (Step 4).
- IG Business account ID: the
- Click Connect. Verification will fetch your username + follower count.
Available actions
- Account details — username, bio, profile picture, follower/follows/media counts
- Recent media — last 100 posts/reels/stories with engagement counts
- Media insights (per post) — impressions, reach, saves, engagement for one media ID
- Reel insights (per reel) — plays, reach, likes, shares, saves, total interactions
- Account insights (date range) — daily impressions, reach, profile views, follower count, website clicks (results auto-pivot to one row per day)
- Audience demographics — gender+age, country, city, locale breakdowns (requires ≥100 followers)
- Stories — currently-live stories
- Hashtag search — resolve hashtag string to ID for hashtag tracking
Common gotchas
- "(#100) Object does not support this operation" — your IG account isn't Business/Creator, or isn't linked to a Page.
- "Invalid OAuth access token" — token expired (likely the short-lived one), or doesn't have the right permissions. Re-run Step 3 or Step 4.
- Empty audience demographics — Meta withholds demographic data unless you have ≥100 followers.
- Graph API version — gptsheet uses
v19.0, supported by Meta through mid-2026. We'll bump it before deprecation.
PostHog
- PostHog → Settings → Account → Personal API Keys → Create. Grant
project:readscope (and any others you want). - Paste the key into gptsheet — the Project field auto-populates with a dropdown of projects you can access (no need to manually look up the Project ID).
- Host is usually
https://us.posthog.com(orhttps://eu.posthog.comfor EU). - Paste all three → Connect.
Amplitude
- Amplitude → Settings → Projects → your project → API Keys.
- Copy API Key and Secret Key.
- Paste both → Connect.
Ghost
- Ghost Admin → Settings → Integrations → Add custom integration.
- Copy the API URL shown on the integration page (e.g.
https://yourblog.ghost.io) — that's the Site URL we ask for. - Copy the Admin API Key from the same page. It looks like
6a1e5be944a3670001ab3704:02a287ee138878...— a 24-char id, a colon, then a 64-char secret. Paste it whole. - Paste both → Connect.
Notion
- Go to notion.so/my-integrations → New integration.
- Name it, copy the Internal Integration Token (starts with
secret_). - In each Notion database or page you want gptsheet to read, click … → Add connections → pick your integration.
- Paste the token → Connect.
Airtable
Pull records, search by formula, get base + table schema. Bases + tables + IDs are discoverable in-app via the "Get base schema" action.
Setup
- Go to airtable.com/create/tokens → Create new token.
- Name it
gptsheet. - Under Scopes, tick both:
data.records:read— required for List records, Get a record, etc.schema.bases:read— required for List bases, Get base schema. Don't skip this — schema-discovery actions will return HTTP 403 without it.
- Under Access, either pick specific bases or select "All current and future bases" if you want one token to work across everything.
- Click Create token → copy the value (starts with
pat; shown only once). - In gptsheet → Connectors → Airtable → paste the token → Connect.
Finding base + table IDs
After connecting, run the List bases action — it returns every base your token can see with its appXXXXXXXXXX ID. Then run Get base schema with that ID to see every table's name + ID + field schema. Use these IDs in subsequent record-fetch actions.
Already created a token without schema.bases:read?
You don't need a new token — Airtable lets you edit existing tokens. Open airtable.com/create/tokens → click your token → add the scope → Save. The existing token immediately gains the new permission; no need to re-paste anywhere.
MySQL
- You need a publicly-reachable MySQL host (RDS, Cloud SQL, PlanetScale, your own VPS). Apps Script cannot reach hosts in private VPCs without a tunnel.
- Create a read-only DB user:
CREATE USER 'gptsheet'@'%' IDENTIFIED BY '...'; GRANT SELECT ON yourdb.* TO 'gptsheet'@'%'; - Allow Google Apps Script's outbound IP ranges through your security group (docs).
- Paste host + port (3306) + database + user + password → Connect.
MS SQL Server
- Public-reachable Azure SQL or self-hosted SQL Server.
- Create a read-only login + map to a DB user with SELECT permissions.
- Allow Apps Script outbound IPs through firewall.
- Paste host + port (1433) + database + user + password → Connect.
Postgres
Direct JDBC connection to any publicly-reachable Postgres — RDS, Cloud SQL, Neon, DigitalOcean Managed Postgres, or self-hosted on a VPS.
Setup
- You need a publicly-reachable Postgres host. Apps Script cannot reach hosts in private VPCs without a tunnel.
- Create a read-only DB user:
CREATE USER gptsheet WITH PASSWORD '...'; GRANT CONNECT ON DATABASE yourdb TO gptsheet; GRANT USAGE ON SCHEMA public TO gptsheet; GRANT SELECT ON ALL TABLES IN SCHEMA public TO gptsheet; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO gptsheet;
- Allow Apps Script's outbound IP ranges through your security group (Apps Script JDBC IPs). For RDS: add the documented ranges to the inbound rule for port 5432.
- In gptsheet → Connectors → Postgres: paste host + port (default 5432) + database + user + password → Connect.
Hosted Postgres specifics
- AWS RDS: ensure the instance has Public access = Yes. Add Apps Script's IP ranges (or temporarily
0.0.0.0/0for a quick test) to the security group's inbound port 5432. - Google Cloud SQL: enable a public IP on the instance; add Apps Script's IPs as authorized networks.
- Neon: the Neon Postgres endpoint is publicly reachable by default. Copy host + database + user + password from the dashboard. Use
requireSSL mode (Neon enforces TLS). - Supabase Postgres direct: use the Connection Pooler endpoint (port 5432) from Project Settings → Database. The host looks like
aws-0-us-east-1.pooler.supabase.com. Or use the dedicated Supabase connector if you'd rather go through PostgREST + service_role.
If verification times out after 20 seconds, that's almost always a firewall — the connection never reaches Postgres. Double-check your security group inbound rules for port 5432, and that the host is reachable from the public internet.
Supabase
- Supabase Project Settings → API Keys.
- Click the "Legacy anon, service_role API keys" tab (the newer Publishable / Secret keys are not yet supported).
- Copy the service_role secret value — it's the second row, labeled
secretin red. - Grab your Project URL from the address bar or Project Settings (format:
https://<ref>.supabase.co). - Paste both into gptsheet → Connect.
The service_role key bypasses Row Level Security. Treat it like a database password — never expose it in client code. The Supabase docs recommend rotating it immediately if leaked.
DynamoDB
- AWS Console → IAM → Users → Create user. Name it
gptsheet-dynamo(or anything you like). Skip the "Provide user access to console" box. - On the next screen ("Set permissions"), pick Attach policies directly → Create policy (opens a new tab). Switch to the JSON tab and paste:
{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": [ "dynamodb:ListTables", "dynamodb:DescribeTable", "dynamodb:Scan", "dynamodb:Query", "dynamodb:GetItem", "dynamodb:BatchGetItem", "dynamodb:ExecuteStatement", "dynamodb:PartiQLSelect" ], "Resource": "*" }] }Name itgptsheet-dynamodb-readonly→ Create policy. Back on the user-creation tab, refresh the policy list, tick it, → Next → Create user. - Open the new user → Security credentials tab → Create access key → choose "Third-party service" → Next → Create. Copy the Access key ID and the Secret access key immediately — the secret is shown only once.
- Find the AWS region where your tables live (e.g.
us-east-1,us-east-2,eu-west-1). DynamoDB is regional — keys created in your account work in every region, but the connector needs to know which region to query. - In gptsheet → Connectors → DynamoDB: paste region + access key ID + secret → Connect. Leave Session token blank unless you're using STS temporary credentials.
The granular PartiQLSelect action is what the AI SQL Builder and Custom PARTIQL Query box use — it's distinct from ExecuteStatement. Without it you'll see "not authorized to perform: dynamodb:PartiQLSelect". The policy above grants read-only access; if you want gptsheet to also write data, add PartiQLInsert, PartiQLUpdate, PartiQLDelete, PutItem, UpdateItem, DeleteItem — but we recommend keeping it read-only.
Pricing
| Basic | Premium | |
|---|---|---|
| Price | $69 lifetime | $99 lifetime |
| Formulas | 13 core | All 16 (+ vision, web, image) |
| Providers | OpenAI + Anthropic | + Gemini + Groq + others |
| Sidebar tools | Custom Prompt, Bulk Apply, API Fetcher | + Chat Agent |
| Updates | 1 year | Lifetime |
| Support | Priority email |
One license = one account.
Privacy
gptsheet is built around a local-first data flow:
| Component | Sees your data? |
|---|---|
| Our server (Supabase) | Never. Only stores license key + bound email. |
| Your browser (sidebar tools) | Yes — sends data directly to your chosen LLM provider over HTTPS. |
| Google Apps Script runtime (cell formulas) | Yes — same trust boundary as your spreadsheet itself. |
| LLM providers (OpenAI, Anthropic, Gemini) | Yes — per their privacy policies. You're a direct customer. |
Read our full privacy policy.
Updates
Basic users get all updates released within 1 year of purchase. After that, your existing version keeps working forever — you just don't get new formulas or provider integrations released after the cutoff. Upgrade to Premium any time for lifetime updates.
Premium users get every update, forever. New formulas, new providers, new sidebar features — all included.
Refunds
All sales are final. If you run into a bug or activation problem, email support@gptsheet.com and we'll work with you to fix it.
FAQ
Why is gptsheet cheaper than GPT for Work?
GPT for Work bundles the LLM cost into expiring credit packs. We don't — you pay providers directly. For a moderate user, that means $1–3/month in LLM costs vs $29–$299 in expiring GPT for Work credits.
Do you train on my data?
No — our server never sees your sheet data, prompts, or LLM responses. Your data flows directly to the LLM provider you chose; how they handle it is governed by their privacy policy (OpenAI, Anthropic, and Google all support API opt-out from training).
Can I use a local model with Ollama?
Premium tier supports custom OpenAI-compatible endpoints. Point at http://localhost:11434/v1 and run any model you've pulled. Useful when you want zero outbound LLM calls.
Does it work in Excel?
Yes. Same formulas, same sidebar UI, same chat agent. One license covers both Google Sheets and Microsoft Excel.
What happens after my 1-year Basic updates window ends?
Your existing version keeps working forever. You stop receiving new features released after the 1-year mark. Upgrade to Premium any time for lifetime updates, or stay on your current version indefinitely.
Troubleshooting
"Google hasn't verified this app" warning
Expected for newly-published add-ons before Google completes OAuth verification (usually 2-6 weeks after submission). Once verified, the warning disappears for all users.
To proceed in the meantime: click Advanced → Go to gptsheet (unsafe) → Allow. The "unsafe" label is generic — it does not mean the add-on is malicious; only that the verification review is still pending.
HTTP 429 from OpenAI when generating images
Cloudflare rate limit triggered by OpenAI's DALL·E 3 service on free / Tier 0 accounts. Switch to a Gemini image model:
=IMAGE(AI_IMAGE("a green apple", "", "gemini-2.5-flash-image"))
"Authorization required" / "Specified permissions are not sufficient"
Apps Script triggers re-authorization when scopes change (e.g. we added Drive access for image generation). To re-grant:
- Open Extensions → Apps Script from your sheet.
- Pick any function in the toolbar and click Run.
- Approve the re-authorization dialog. New scopes are added to your existing grant.
Cell shows [gptsheet] OpenAI key not set
The cell formula needs its key synced to Apps Script. Open the sidebar → ≡ → API keys → edit OpenAI → Save. (Saving also syncs to formulas.)
Need more help?
Email support@gptsheet.app. Premium customers get priority response (typically within 24h).