Looking for Javascript instead of Python? Visit our Code (Javascript) documentation.
With Zapier's Code action you can extend our platform to do just about anything using one of the simplest programming languages available - Python! Run code in response to any trigger that Zapier supports.
Some example use cases include:
requests without building a full dev app.Warning - this is advanced stuff! You probably need to be a programmer to use this - though you are welcome to play with it. Technical support for bugs in your code is not provided!
The environment is vanilla Python 2.7.10. Your script is sandboxed and can only run for a limited amount of time and within a limited amount of memory. If you exceed those limits - your script will be killed (you can upgrade to a paid Zapier to increase your limits).
Since the amount of data that might feed into your script might be large or highly dynamic - you'll need to define an input mapping via our GUI. This is a really simple step - the screenshot below shows a very basic example:

Scroll to the examples section to see an assortment of starter scripts.
In your code you will have access to a few variables:
input_data
The dictionary of data you did right above your code snippet (not available in triggers). All values will be strings.output
A dictionary or list of dictionaries that will be the "return value" of this code. You can explicitly return early if you like. This must be JSON serializable!Note: you may see old code examples using
inputwhich we changed toinput_datato reduce confusion. Both work - but we prefer the less confusioninput_datasinceinputwas a built in function for Python!
requests
An easy to use HTTP client - read the documentation here.StoreClient
An easy to use database or cache for stashing key & values to maintain state between runs - read the documentation here.print
Super helpful if you want to debug your function - you'll need to test your zap to see the values (the logs are returned to you in a runtime_meta added automatically to your output).Running your zap via the dashboard or the editor is the canonical way to confirm the behavior you expect - your Task History will have all relevant details around the ran code's input_data, output and logs. Step 6 (the test step) in the editor can be used for a tighter feedback loop.
Try asking for by tagging questions as Zapier on Stackoverflow!
Important! Every example depends on specific
input_data- which is provided under the "Input Data" field when setting up your - this example screenshot shows three demonstration inputs you can use in your code like this:input_data['body'],input_data['name'], andinput_data['subject']. Be sure you read the code examples and provide the right inputs otherwise nothing will work as expected!
In this section we provide some examples - it is important to note that Python is an advanced programming language - if you get lost it might make sense to ask a programmer friend or learn python yourself.
Each of the four examples below expects a name in the "Input Data" field.
A easy example might be something as trivial as:
return {'id': 1234, 'hello': 'world!', 'name': input_data['name']}
You can also bind the result to output - the code above has exactly the same behavior as the code below:
output = {'id': 1234, 'hello': 'world!', 'name': input_data['name']}
You'll notice that when it comes to code - you can solve the same problems in hundreds of unique ways!
An example with an early empty return might be something as trivial as:
if input_data['name'] == 'Larry':
return [] # we don't work for Larry!
return {'id': 1234, 'hello': 'world!', 'name': input_data['name']}
If you return an empty list
[], we will not trigger any actions downstream that depend on the code step's output (they will be halted). However, other steps that don't depend on the code step's output will still run unless a filter stops the Zap from going further.
A more complex example (no "Input Data" needed):
response = requests.get('http://example.com/')
response.raise_for_status() # optional but good practice in case the call fails!
return {'id': 1234, 'rawHTML': response.text}
This example expects a name in the "Input Data" field:
if input_data.get('name'):
print 'got name!', input_data['name']
return {'id': 1234, 'hello': 'world!', 'name': input_data['name']}
Test your action and look at the data to see the
This example expects a rawNumber in the "Input Data" field:
return {
'calculatedNumber': int(input_data['rawNumber']) / 2
}
This example expects a rawText in the "Input Data" field:
import re
emails = re.findall(r'[\w._-]+@[\w._-]+\.[\w._-]+', input_data['rawText'])
return {
'firstEmail': emails[0] if emails else None
}
This example expects a rawText in the "Input Data" field:
import re
emails = re.findall(r'[\w._-]+@[\w._-]+\.[\w._-]+', input_data['rawText'])
return [
{'email': email} for email in emails
]
This will trigger multiple downstream actions - one for each email found! If no emails are found - nothing happens.
There may be cases where you need to create a comma separated list but you need to eliminate the blank values from the list. This snippet will help you create the list and remove blanks. This example expects a values entry in the "Input Data" field like this:

import re
values = re.sub('(^,+|,+$)', '', input_data['values'])
values = re.sub(',+', ',', values)
return [{'values': values}]
This example expects a zipCode in the "Input Data" field:
zc = input_data['zipCode']
url = 'http://api.openweathermap.org/data/2.5/weather?zip=' + zc + ',us'
response = requests.get(url)
response.raise_for_status() # optional but good practice in case the call fails!
return response.json()
It isn't uncommon to want to stash some data away for the next run, our StoreClient can do exactly that. For example - this is a counter that counts how many times it is ran:
store = StoreClient('some secret')
count = store.get('some counter') or 0
count += 1
store.set('some counter', count)
return {'the count': count}
In conjunction with a Filter step, you could use code like this to limit the number of times your zap can run per hour (which is configurable):
every_seconds = 60 * 60
store = StoreClient('some secret')
import time
now = int(time.time())
last_post = store.get('last_post') or now - every_seconds + 1
output = {'run': 'no'}
if last_post < (now - every_seconds):
output = {'run': 'yes'}
store.set('last_post', now)
# don't forget to set up a filter after this that checks if run is exactly yes
Note! Without a follow up Filter step this won't work!
Storing and retrieving data with StoreClient is very simple.
There is no need to import it - it comes pre-imported in your Code environment.
You will need to provide a secret that will protect your data. I recommend using Random.org's excellent password generator. Be very sure you pick a complex secret - if anyone guesses it they'll be able to read and write your data!
Instantiating a client is very simple:
store = StoreClient('your secret here')
Most likely you just want to get and set some values - this is the simplest possible example:
store = StoreClient('your secret here')
store.set('hello', 'world')
value = store.get('hello') # return 'world'
store.delete('hello')
If the value doesn't exist during your get() call - it will return a None value.
You can also save and retrieve multiple keys and values - a slightly more complex example:
store = StoreClient('your secret here')
store.set_many({'hello': 'world', 'foo': 'bar'})
values = store.get_many('hello', 'foo') # return {'hello': 'world', 'foo': 'bar'}
store.delete_many('hello', 'foo')
store.clear() # or, if you want to wipe everything
Note, you can call get_many and delete_many in a few different ways:
store.get_many('hello', 'foo') # as args
store.get_many(['hello', 'foo']) # as list
store.get_many({'hello': None, 'foo': None}) # as dict
And similarly with set_many:
store.set_many({'hello': 'world', 'foo': 'bar'}) # as dict
store.set_many(hello='world', foo='bar') # as kwargs
Try asking for by tagging questions as Zapier on Stack Overflow!
Unfortunately you cannot require external libraries or install libraries commonly referred to as "pip modules". Only the standard Python library and requests is available in the Code app and requests is already included in the namespace.
Free users are limited to 1 second and 128mb of RAM. Paid users get well over double that at 10 seconds and 256mb of RAM. Your Zap will hit an error if you exceed these limits.
If you have a python code step that returns a value like this:
return {'result': 1.0}
it may appear up as 1 (not 1.0) in task history and test results. This is an artifact of the UI. The Zapier web UI does not distinguish between int and float values; they are all just numbers. In your Python code step you can use int(aNumber) or float(aNumber) to make sure to convert the value to the data type you require.
Python is a fairly complex language and you should probably be a programmer or willing to dedicate some serious time to learn to code - while we can't help you fix your code, try asking for by tagging questions as Zapier on Stack Overflow.
Coming soon!