fx APIs & Web Apps

PropertiesService: storing settings and API keys

⏱ 10 min

What you'll learn

  • Why API keys and settings shouldn't live in your code
  • Script, user and document properties — which to use
  • Setting values through the UI and from code
  • Size limits and what properties are *not* for

Concept

The problem

const API_KEY = 'sk_live_9f8a…';   // ❌ visible to anyone who can open the script
const ALERT_EMAIL = 'me@example.com'; // ❌ must edit code to change it

Anyone with edit access to the sheet can open Extensions → Apps Script and read the key. If you share a copy of the file, the key goes with it. Settings like email addresses also shouldn't need a code edit.

Three kinds of properties

Store Shared with Use for
getScriptProperties() Everyone running this script API keys, webhook tokens, global settings, counters
getUserProperties() Only the current user Each user's own preferences
getDocumentProperties() Everyone using this file (bound scripts / add-ons) Settings for one particular spreadsheet

Script properties are the ones you'll use most.

Setting values in the UI

  1. Editor → Project Settings (gear icon).
  2. Scroll to Script Properties → Add script property.
  3. Property: API_KEY, Value: your key. Save.

This keeps the key out of your code. It's still visible to people with edit access to the script project, so share edit access only with people you trust.

Reading and writing from code

const props = PropertiesService.getScriptProperties();

// Read
const apiKey = props.getProperty('API_KEY');
if (!apiKey) throw new Error('API_KEY is not set in Script Properties');

// Write one
props.setProperty('ALERT_EMAIL', 'store@example.com');

// Write several
props.setProperties({ GST_RATE: '0.03', CURRENCY: 'INR' });

// Read all as an object
const all = props.getProperties();
console.log(all.GST_RATE);

// Delete
props.deleteProperty('OLD_SETTING');

All values are stored as strings. Convert when reading: Number(props.getProperty('GST_RATE')), or for objects:

props.setProperty('CONFIG', JSON.stringify({ reorderDays: 7, ccManager: true }));
const config = JSON.parse(props.getProperty('CONFIG') || '{}');

A config helper

Put all settings in one place with defaults:

function getConfig() {
  const p = PropertiesService.getScriptProperties().getProperties();
  return {
    alertEmail: p.ALERT_EMAIL || Session.getEffectiveUser().getEmail(),
    gstRate: Number(p.GST_RATE || 0.03),
    apiKey: p.API_KEY || ''
  };
}

Limits and what not to store

  • Each value: about 9 KB. Total per store: about 500 KB.
  • Properties are for small settings, keys and counters — not for data tables. Data belongs in a sheet.
  • Frequently changing values (like a progress pointer) are fine, but reading/writing hundreds of times a second isn't — use CacheService for short-lived data.

Key points

  • Keep secrets and settings out of code: Script Properties.
  • Values are strings — convert numbers and JSON when reading.
  • Fail clearly if a required property is missing.

Exercises

mediumPractice 1

Move every hard-coded ID in your invoice script (template ID, folder ID, GST rate) into Script Properties and read them through a getConfig() helper.

Quiz

Which store is shared by everyone who runs the script? a) User properties b) Script properties c) Cache
Script properties
What type are property values stored as? a) Numbers b) Strings c) Arrays
Strings
PropertiesService: storing settings and API keys · Google Apps Script | ExcelWalaa