How to Migrate from Zapier Functions Before Deprecation: Move to Code by Zapier

Introduction

Zapier Functions, the product that let you write reusable Python functions with triggers, secrets, and authenticated app calls, is gone. Zapier stopped accepting new Functions users on June 1, 2026, and every function stopped running on September 1, 2026. If you are reading this in October 2026 and your functions went silent last month, this guide is your recovery manual. The official migration target is Code by Zapier, the JavaScript and Python code steps that run inside ordinary Zaps, and this tutorial walks you through the full translation: inventorying your dead functions, choosing Python or JavaScript, rewriting zapier.action calls with the Zapier SDK, moving secrets to API by Zapier, and testing before you cut over. It is for automation owners and developers who shipped production logic on Functions and now need it running again.

Quick answer

Rebuild each function as a Zap with a Code by Zapier step: pick Python for plain logic, or JavaScript with the Zapier SDK for app calls and secrets. Functions stopped running on September 1, 2026, so rebuild them.

Evidence: what the official shutdown actually says

Zapier’s own migration guide lays out a two-stage shutdown: June 1, 2026, when Functions stopped accepting new users, and September 1, 2026, when all functions stopped running. As of October 2026, both dates are in the past, so there is no grace period left to plan around. The numbers that matter for the rebuild:

  • 5-minute runtime was the Functions ceiling. Code by Zapier steps can run up to 10 minutes on paid plans, twice as long, while the Free plan allows only 1 second per step with a 2-minute monthly cap. (Zapier migration guide and SDK docs, as of October 2026)
  • 1,500 tasks per month was the Functions quota. Code steps bill under standard task usage, one successful Zap run consuming tasks like any other action step. (Zapier migration guide, as of October 2026)
  • Code steps run on AWS Lambda with a 6 MB I/O limit on code plus processed data, so giant payloads that fit in a Function may need trimming. (Zapier JavaScript code docs, as of October 2026)

The guide’s own framing is blunt about the two features that force a rewrite rather than a copy-paste. For app calls: “Use JavaScript if you need the Zapier SDK.” For secrets: “Do not use fetch for these calls,” directing you to API by Zapier with the SDK instead. And for the hardest case, plain Python without app calls or secrets is the easy win: the guide says you can reuse much of that code in a Python Code step with only input/output handling to update.

Prerequisites

  • A Zapier account (any plan; paid plans are required for third-party npm or PyPI packages and extended runtimes)
  • Your old function code, ideally saved locally before the shutdown, plus a list of which apps, triggers, and secrets each function used
  • Basic familiarity with the Zap editor and either Python or JavaScript
  • If you are reconsidering Zapier itself after this deprecation, skim our Zapier to n8n migration guide first so you are choosing the platform deliberately, not just by default

Step-by-step migration

Step 1: Inventory your functions

Before touching the Zap editor, make a table of what you are losing. For each function, record: the trigger (or triggers, since Functions supported several per function), the apps it called, whether it used zapier.action, which secrets it referenced, which third-party libraries it imported, and how long it typically ran. This inventory decides every later choice. A function with two triggers becomes two Zaps (or one Zap calling a sub-Zap); a function importing BeautifulSoup needs a rethink because, per the official guide, there is no JavaScript equivalent built in.

Step 2: Create one Zap per trigger

Each function trigger becomes a separate Zap trigger. In the Zap editor, create a new Zap and set up the same trigger your function used. If the function had multiple triggers, the official guide gives you two options: create one Zap per trigger, or share the logic through a sub-Zap. Start with the separate-Zaps option unless the logic is genuinely identical, because debugging one trigger’s Zap is far easier than untangling a shared sub-Zap when only one path breaks.

Step 3: Add a Code by Zapier step and pick your language

Add a step, search for Code by Zapier, and choose the action event: Run JavaScript or the Python equivalent. The language choice is the most consequential decision in the whole migration:

  • JavaScript, if your function called apps via zapier.action, used secrets, or made authenticated API calls. The Zapier SDK is JavaScript only; Python steps cannot use it.
  • Python, only if your function was pure logic with no app calls and no secrets. Then you can reuse most of the code and just update how data flows in and out.

Getting this wrong is the classic mistake: porting to Python first, then discovering the app calls need the SDK and starting over in JavaScript. Check your Step 1 inventory before you choose.

Step 4: Translate Python Functions code to the new dialect

The input/output contract changes slightly between the two products. The official mapping is:

  • input_data['key'] becomes inputData.key or inputData['key']
  • output = {'key': 'value'} becomes output = {key: 'value'}
  • print(value) becomes console.log(value)
  • requests.get(url) becomes await fetch(url)
  • requests.post(url, json=data) becomes await fetch(url, {method: 'POST', body: JSON.stringify(data), headers: {'Content-Type': 'application/json'}})
  • try: ... except: becomes try { ... } catch (error) { ... }

A minimal translation looks like this. The Functions version:

import requests

resp = requests.post(
    "https://api.example.com/v1/items",
    json={"name": input_data["name"]},
)
output = {"item_id": resp.json()["id"]}

becomes, in a JavaScript Code step:

const resp = await fetch("https://api.example.com/v1/items", {
  method: "POST",
  body: JSON.stringify({ name: inputData.name }),
  headers: { "Content-Type": "application/json" },
});
const data = await resp.json();
output = { item_id: data.id };

The official docs also note that StoreClient, the built-in key-value store for sharing state between runs, exists in both Python and JavaScript code steps, so persistence code using it ports nearly line for line (it is promise-based in JavaScript, so remember await). If your logic resembles what the n8n Code node does in JavaScript workflows, the mental model transfers directly.

For anything language-specific, the official JavaScript code docs describe the editor flow: write code, map trigger data through the Input Data fields, click Run Code, and inspect the Output Data panel to verify the step.

Step 5: Replace zapier.action calls with the Zapier SDK

zapier.action was the Functions-only helper for calling authenticated app actions; it does not exist in Code by Zapier. The replacement is the Zapier SDK in a JavaScript step. Per the SDK docs, you enable it by clicking the Packages icon in the Code step and toggling @zapier/zapier-sdk (latest) on, which auto-imports the package. Zapier handles authentication from your existing app connections, and the docs state that “credentials are never exposed in your code, Zap history, or logs.”

The SDK pattern, adapted from Zapier’s documented example, finds a connection and calls a write action:

import { createZapierSdk } from '@zapier/zapier-sdk';

const zapier = createZapierSdk();

export default async function main({ inputData }) {
  const { data: slackConn } = await zapier.findFirstConnection({
    appKey: "slack",
    owner: "me",
    isExpired: false,
  });
  const slack = zapier.apps.slack({ connectionId: slackConn.id });
  const { data: result } = await slack.write.direct_message({
    inputs: { channel: inputData.channel, text: inputData.message },
  });
  return { sent: true, result };
}

Note two ownership rules from the docs: the SDK is JavaScript only, and only the Zap owner can add connections to an SDK step, so coordinate with the owner if you are a collaborator.

Step 6: Move secrets to API by Zapier

Code by Zapier cannot store secrets the way Functions could, and hard-coding API keys into a code step is both insecure and brittle. The official path for custom APIs and token-based auth is API by Zapier: you create a connection that holds the credentials, then call it from the SDK instead of fetch. The migration guide is explicit here: “Do not use fetch for these calls.”

The API by Zapier docs describe adding an API by Zapier action with the API Request event, choosing or creating a connection, and sending GET, POST, PUT, PATCH, or DELETE to any URL. The connection stores the credentials, so the secret never appears in your code or Zap history. API by Zapier is a premium app, so this path assumes a paid plan.

Step 7: Handle multi-file functions and long runtimes

Functions let you split code across files and run up to 5 minutes. Code by Zapier gives you one code editor per step, so combine files into a single step or split the logic across several Code steps in the same Zap. For runtimes, paid plans allow up to 10 minutes per step, which covers most Functions workloads, but Free-plan steps die after 1 second with a 2-monthly cap of 2 minutes. If a function processed large batches near the old 5-minute ceiling, test the ported version on a paid plan and watch the 6 MB I/O limit, since the code plus all processed data must fit inside it.

Step 8: Test, remap downstream steps, and cut over

Test each Zap step in the editor with the Run Code button, then remap any downstream steps that consumed the function’s old output shape, because field names may have changed in translation. Publish the Zap, run it end to end against real data, and only then stop or delete the original function. The official guide points to Zap version history as your rollback mechanism, the Code-by-Zapier equivalent of Functions’ deploy and rollback, so publish deliberately and check the first production runs in Zap history.

Troubleshooting

1. The Code step dies instantly on the Free plan

Cause: Functions gave you 5 minutes of runtime; the Free plan gives a Code step 1 second per run and 2 minutes per month. Anything with an HTTP call, a loop, or SDK orchestration blows past 1 second. Fix: upgrade to a paid plan for up to 10 minutes per step, or split the work across multiple Code steps so each stays under the limit. Re-estimate runtimes from your Step 1 inventory before migrating.

2. Cannot find module or a PyPI package fails to install

Cause: third-party npm and PyPI packages are a paid-plan feature, and each package must be added through the Packages icon in the Code step, not via import alone. Fix: on a paid plan, add the exact package and version through the Packages UI, then test. Also check the language table: libraries like BeautifulSoup have no JavaScript equivalent in the official mapping, so a Python step (with PyPI) may be the right call for HTML parsing workloads.

3. zapier.action is not defined

Cause: zapier.action only existed inside Zapier Functions. It is not available in Code by Zapier, and pasting function code verbatim always breaks here. Fix: rewrite the call in JavaScript using the Zapier SDK pattern from Step 5. The migration guide’s rule of thumb is that anything touching apps moves to JavaScript with the SDK, since “Use JavaScript if you need the Zapier SDK.” If the call was a simple HTTP request without app auth, plain fetch works.

4. The SDK step fails with expired or missing connections

Cause: the SDK authenticates through your Zapier app connections. Expired connections produce runtime errors, and only the Zap owner can attach connections to an SDK step, so a collaborator’s edit can silently break auth. Fix: re-authenticate the connection in the Zap editor, and have the Zap owner attach the connections. The documented findFirstConnection call accepts an isExpired: false filter, so your code skips dead connections instead of failing on them.

5. Secrets from Functions have nowhere to live

Cause: Functions had a secrets store; Code by Zapier does not, and pasting tokens into code exposes them in Zap history and logs. Fix: move credentials into an API by Zapier connection and call it through the SDK, per Step 6. The official guide forbids the shortcut: “Do not use fetch for these calls.” If the platform deprecation has you questioning Zapier altogether, our Zapier to n8n migration guide compares the full-platform alternatives with real pricing math.

Conclusion

The Zapier Functions shutdown is a forced rebuild, not an optional upgrade: the June 1 cutoff already passed, the September 1 shutdown already happened, and dead functions will not come back. The migration itself is mechanical once you inventory triggers, app calls, secrets, and libraries, then translate to Code by Zapier with the SDK for anything authenticated. Start with your highest-traffic function, prove the pattern once, and the rest follow the same template. If the exercise leaves you wanting real version control and self-hosting for your code workflows, the next read is our Zapier to n8n migration guide, which weighs staying against switching; for the broader platform picture, our n8n vs Make comparison for AI agents covers where each platform’s code story stands. Pair either with our n8n error handling tutorial for patterns that survive production.

Frequently asked questions

Did Zapier Functions already shut down?

Yes. Zapier stopped accepting new Functions users on June 1, 2026, and all functions stopped running on September 1, 2026, according to Zapier's official migration guide. If you missed the window, your functions are already dead, but the migration path to Code by Zapier still works exactly as described in this guide.

Can I still recover my function code after the shutdown?

Zapier's official guidance was to copy your Python code locally before September 1, 2026. If you did not, check whether functions.zapier.com still serves your dashboard, and contact Zapier Support if it does not. Without the original code you will have to rewrite from your own notes or version history.

Should I pick Python or JavaScript for the Code by Zapier step?

Use JavaScript if you need the Zapier SDK or API by Zapier, which is how you call authenticated apps and replace secrets. Use Python only for plain logic with no app calls and no secrets, since the SDK does not support Python.

Do I need a paid Zapier plan to migrate?

Not necessarily. The Zapier SDK works on all plans, including Free, per Zapier's docs. You need a paid plan for third-party npm or PyPI packages and for extended runtimes up to 10 minutes. The Free plan allows 1 second of per-step runtime with a 2-minute monthly cap.

What happens to the 1,500 tasks per month quota Functions included?

That quota is gone with the product. Code by Zapier steps count under standard task usage: each successful Zap run consumes tasks the same way any other action step does, so re-estimate your volume against your plan's task pool.

Can I rebuild without writing any code?

Sometimes. If your function only called one or two app actions, the equivalent native Zapier actions may cover it. But multi-file Python, custom secrets handling, and zapier.action orchestration have no no-code equivalent, which is why the official guide points you to Code by Zapier.

TP
ToolPilot Team

We install, break, and fix automation tools so you don't have to. Every tutorial on ToolPilot is tested hands-on before publishing.

Keep reading