Automation Blog

Zapier Storage API: How to Store and Retrieve Persistent Data Across Zaps

How to use the Zapier Storage API at store.zapier.com to persist key-value data between Zap runs — storing counters, deduplication flags, last-run timestamps, and shared state that multiple Zaps can read and write.

ZapierStorage APIAdvanced Zapier

By Troy Tessalone · · 5 minutes

Automation Guide

A practical field guide from Automation Ace.

Zapier Storage API: How to Store and Retrieve Persistent Data Across Zaps

Zapier Zaps are stateless by design — each Zap run is independent, with no memory of previous runs. Data flows in through the trigger, passes through action steps, and exits through the final action. There is no built-in way for a Zap to remember what it did last time, count how many times it has run, or share a value with another Zap. The Zapier Storage API changes this. It is a simple key-value store hosted by Zapier, accessible via HTTP from Code steps, that gives Zaps a persistent memory layer. This guide covers how the Storage API works, how to read and write values, and the common patterns it enables.

What the Zapier Storage API Is

The Zapier Storage API (available at store.zapier.com) is a Zapier-provided key-value store. It is:

  • Persistent: Values stored survive between Zap runs — they do not reset when a Zap completes
  • Shared across Zaps: Multiple Zaps using the same secret key can read and write the same storage namespace, enabling inter-Zap coordination
  • Simple: A REST API with GET (read), POST (write), and DELETE (remove) operations on key-value pairs
  • Authenticated by secret: Each storage namespace is identified by a secret string you generate — anyone with the secret can access the values

The Storage API is most useful in Code steps, where you call it directly via fetch (JavaScript) or requests (Python). It is also accessible via Webhooks by Zapier actions for simpler read/write operations without a Code step.

Getting a Storage API Secret

To use the Storage API, you need a secret key that identifies your storage namespace. Generate one at store.zapier.com — log in with your Zapier account and create a secret. Store this secret value securely; it authenticates all read and write operations to your namespace. Treat it like an API key — do not hard-code it in shared Zaps; pass it as a Code step input variable instead.

Reading a Value from Storage

To read a stored value in a JavaScript Code step:

const secret = inputData.storage_secret; // passed as input variable
const key = 'my_counter';

const response = await fetch(`https://store.zapier.com/api/records?secret=${secret}`);
const data = await response.json();

output = {
  value: data[key] !== undefined ? String(data[key]) : '0',
  all_values: JSON.stringify(data)
};

The GET endpoint returns all key-value pairs in your namespace as a JSON object. Access the value by key name. If the key does not exist yet, handle the undefined case with a default value.

Writing a Value to Storage

To write or update a value:

const secret = inputData.storage_secret;
const key = 'my_counter';
const newValue = parseInt(inputData.current_value || '0') + 1;

const response = await fetch('https://store.zapier.com/api/records', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-Secret': secret
  },
  body: JSON.stringify({ [key]: newValue })
});
const data = await response.json();

output = {
  stored_value: String(newValue),
  success: response.ok ? 'true' : 'false'
};

The POST endpoint accepts a JSON object of key-value pairs to set. Multiple keys can be written in a single request. Values can be strings, numbers, or any JSON-serializable type.

Read-Modify-Write: Incrementing a Counter

The most common Storage API pattern combines a read and a write in a single Code step — read the current value, compute the new value, write it back:

const secret = inputData.storage_secret;
const key = 'run_count';

// Read current value
const readResponse = await fetch(`https://store.zapier.com/api/records?secret=${secret}`);
const store = await readResponse.json();
const currentCount = parseInt(store[key] || '0');
const newCount = currentCount + 1;

// Write new value
await fetch('https://store.zapier.com/api/records', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json', 'X-Secret': secret },
  body: JSON.stringify({ [key]: newCount })
});

output = { run_count: String(newCount), previous_count: String(currentCount) };

Practical Use Cases

Deduplication: Has this record been processed?

Store a flag keyed by a record ID to prevent the same event from being processed twice:

const key = `processed_${inputData.record_id}`;
const readResp = await fetch(`https://store.zapier.com/api/records?secret=${inputData.secret}`);
const store = await readResp.json();

if (store[key]) {
  output = { already_processed: 'true' };
} else {
  // Mark as processed
  await fetch('https://store.zapier.com/api/records', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', 'X-Secret': inputData.secret },
    body: JSON.stringify({ [key]: 'true' })
  });
  output = { already_processed: 'false' };
}

Follow this Code step with a Filter: only continue if already_processed equals false. This prevents duplicate processing even when the same trigger fires multiple times for the same event.

Last-run timestamp

Store the timestamp of the last successful Zap run, readable by a monitoring Zap or a reporting Zap that needs to know when the previous run occurred.

Running totals and monthly counters

Accumulate a running total across Zap runs — for example, a total of invoices processed this month. Reset the counter at month-end by writing 0 back to the key.

Cross-Zap coordination

Zap A writes a flag to Storage when a process starts. Zap B checks for that flag before proceeding, preventing race conditions when two Zaps might otherwise process the same resource simultaneously.

Limitations to Know

  • Not a database: The Storage API is a flat key-value store — no querying, filtering, or sorting. For structured data, use Airtable or a Google Sheet
  • No atomic operations: Read-modify-write is two separate HTTP calls — there is a small window where two concurrent Zap runs could read the same value before either writes back (race condition). For high-concurrency scenarios, add a short delay or use a dedicated database
  • Data size limits: Individual values should be kept small — the Storage API is not designed for storing large payloads or files
  • Secret management: The secret grants full read/write access to all keys in the namespace — treat it accordingly and rotate it if compromised
The Zapier Storage API is the missing memory layer for Zap workflows. It solves a class of problems that would otherwise require an external database: deduplication, counters, flags, last-run tracking, and inter-Zap state sharing. For anything that needs to persist between runs, Storage is the lightest-weight solution available inside the Zapier platform.

For more on building logic into Zapier workflows with Code steps, see JavaScript libraries in Zapier Code steps and how to make HTTP POST requests from a Zapier Code step. For help designing a stateful Zapier workflow, talk to Automation Ace.

ZapierStorage APIAdvanced Zapier

Disclaimer: This article may include links to apps, products, or services. Some links may be affiliate links, which means Automation Ace may earn a commission at no extra cost to you.

Build Better Systems

Ready to automate with confidence?

Share your tools, process, and goals. Automation Ace can design the workflow, integration, AI assist, or code bridge that fits your business.

Start a Project