`, where `target_url` is the unique target URL that was provided when the subscription was created. This will pause the Zap within Zapier.
Once you've configured all the endpoints, click *Save API Request & Continue*
## 4. Test your API request
To test the REST Hook trigger, [build a Zap in the editor](/platform/build/test-triggers-actions).
## 5. Define your output
Define sample data and output fields following [the guide](/platform/build/sample-data).
## Video Tutorial
You can refer to this video on REST Hook triggers:
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Hydration/dehydration limits
Source: https://docs.zapier.com/platform/build/hydration-limits
[File dehydration](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#dehydration) is an extremely useful tool to remain within time and size constraints for Zapier triggers and actions. However, it does have its own limits.
## Constraint
There is a hard limit of 150MB on the size of dehydrated files. Depending on the complexity of the app, issues can also occur for files over \~100MB.
## Errors user will see if constraint is hit
* In their Zap history, the user will see an error like `Runtime exited with error: signal: killed`.
## Best practice
If your integration regularly loads large files, provide checks on file size and don't perform hydration for files that are larger than \~100MB. Include messaging for users letting them know of the limit on file size in the trigger/action description or in a `Copy` field above the file input field.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Add line item group field to actions
Source: https://docs.zapier.com/platform/build/line-items
Input fields in Zapier add one item each time the Zap runs. But, if you want users to be able to add multiple items in a single Zap run, then this can be achieved by using a line item group. This group takes line items, which are comma-separated values, and adds each instance of the values to the app in a single Zap run.
**Tip**: Learn more about line items from Zapier's [guide](https://zapier.com/blog/formatter-line-item-automation/) and [help documentation](https://help.zapier.com/hc/en-us/articles/8496277737997).
Line items can be challenging for users to work with as a concept, so make sure to consider what a user would be inputting and do not add line item group fields unless there is a clear use case for them.
## Before adding a line item group
Before adding a line item group to an action:
* You should have already added an [action](/platform/build/action) where this line item group would be added.
* Your app's API should be able to accept and work with line item values.
## Add a line item group
To add line item group to an action:
1. Log into the [Platform UI](https://zapier.com/app/developer).
2. Select your **integration**.
3. In the *Build* section in the left sidebar, click the **name of your action**.
4. Click the Input Designer tab
5. Click \*\*Add
dropdown menu and select **Line Item Group**.
6\. In the **Line Item Group Label** field, add a name for the Line Item Group. This should be something users would recognize as being a set of values where each one would be added individually.
7\. In the **Line Item Group Key** add a key for the Line Item Group. This will let Zapier identify this group internally.
8\. Click the **Add Line Item** button.
9\. Add in the relevant fields as you would for a [input field](/platform/build/field-definitions#add-fields). Each field that you add here will be received as line item values. Note the *Allows Multiples* and *Alters Dynamic Field* options will not appear as those options cannot be used in line item fields as they are mutually exclusive.
10\. After adding all the line item fields, click **Save**.
Your new Line Item groups will show up in the Zap editor as a separate block with the different line item input fields within:
Users will need to map line item values from earlier steps in their Zap into the fields within the line item group. They would be sent to your API as an array of individual objects. Users cannot input comma separated values into a line item field, they need to be provided from the trigger or a prior action in line item format for them to be sent this way.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Add authentication with OAuth v2
Source: https://docs.zapier.com/platform/build/oauth
OAuth v2 authentication matches in appearance the login process users expect from most modern apps.
The user interaction with authenticating Zapier typically takes place in full on the app's own site, helping users easily connect accounts without needing to share account credentials or look up API keys.
The user will see a familar window from your app showing either a login screen or if they're already logged in, an account selector where they don't need to enter credentials. Once they authorize Zapier access, the app will return an access token that Zapier uses in future API calls.
Zapier implements the “Authorization Code” [grant type](https://tools.ietf.org/html/rfc6749#section-1.3.1) when you choose OAuth v2 in the Platform UI. If your OAuth v2 implementation supports refresh tokens, you can optionally configure a “Refresh Token” [request](https://tools.ietf.org/html/rfc6749#section-1.5).
Platform UI does not currently support other grant types. If your integration requires a different OAuth v2 grant type, you'll need to use another supported authorization type with Zapier such as [Session](/platform/build/sessionauth) or [API Key](/platform/build/apikeyauth).
If your integration requires OAuth v1 authentication, use the [Platform CLI](/platform/quickstart/cli-tutorial) instead of Platform UI.
## 1. Configure the OAuth v2 components
* Open the *Authentication* tab in Zapier visual builder and select *OAuth v2*.
### Optional input form
* Most apps with OAuth v2 authentication do not need an input form. If your API requires data from the user before displaying the authorization URL, or requires URL details to create the authorization URL; such as account team name or site URL for self-hosted apps, or you need to store fields received from your server to use in subsequent API calls - you'll need an input form.
* Add those additional fields by selecting *Add Fields* and fill in the details for any field requiring user input. This will show a form to users with the fields you've added before redirecting them to your authorization URL.
* Two types of fields are available when building an OAuth v2 input form. Standard Fields, work much like other form fields with Zapier's [input form](/platform/build/field-definitions) in triggers and actions. [Computed Fields](/platform/build/computed-fields) make sure specific fields are returned by your app's authentication API call response.
* For standard fields to be input by the user, select the default *Field* type. Add the most commonly needed fields first, in the order users expect, as you cannot reorder fields once added. Fill in the options as appropriate:
– **Key**: The internal name for your field, used to reference this field in Zapier API calls. For convenience, use the same key as your API uses for this field. Note: `client_id` and `client_secret` are reserved and cannot be used as keys for input form fields.
– **Label**: A human-friendly name for this field that will be shown to users in the authentication form.
– **Required? (checkbox)**: Check if this field is required for successful authentication.
– **Type**: All input fields use the `string` text field by default; select `password` instead if you would like to obscure the data as users enter it.
– **Help Text**: Include details to assist users in authenticating with your app, especially if they may be unsure where to find the data needed within your app. Format text with [Markdown](https://zapier.com/blog/beginner-ultimate-guide-markdown/), and include a hyperlink if needed.
– **Input Format**: (optional) Help users figure out exactly what piece of data you need them to enter. For example, for [a subdomain](/platform/build/subdomain-validation), [https://.yourdomain.com/](https://.yourdomain.com/).
– **Default Value**: Include a value for this field to be used as a fallback. For optional fields, the default value is set on initial connection creation and used in the API call instead of missing or null values every time the Zap runs. For required fields, this value is used during connection creation, but not when the Zap runs (Zapier raises an error for missing/null values instead).
* Input fields marked as password and all authentication fields with sensitive, private data such as both username and password from OAuth v2 are automatically censored at runtime. These values are stored in the Auth bundle and used in API calls, but are replaced in Zapier's logs with a censored value like this `:censored:6:82a3be9927:`. Due to this, it is not possible to view the exact tokens or keys in Zapier's logs. To verify that the same token as was returned by the authentication, is being used in subsequent API calls; you can compare censored value characters, for example `:censored:6:82a3be9927:` would have the same value ending in 9927 when used in a subsequent call.
* Each input field is listed with its label, key, type, and required status in your authentication settings. Click the field to edit it, or click the gear icon and select *Delete* to remove a field.
* For computed fields, available in OAuth v2 and Session Auth only, review [computed fields documentation](/platform/build/computed-fields).
### OAuth Redirect URL
* Open your app's application, integration, or API settings, and add a new application for your OAuth integration with Zapier. From the Zapier Platform UI's Authentication *Copy your OAuth Redirect URL* section, copy the OAuth Redirect URL and add it to your application's integration settings.
* To reference the redirect URL inside your Zapier integration, use the following code:
`{{bundle.inputData.redirect_uri}}`
### Add PKCE Support
* Zapier provides built-in support for [PKCE](https://oauth.net/2/pkce/#credentials) (Proof Key for Code Exchange and pronounced “pick-see”), an extension to the authorization code flow that adds a layer of protection against security vulnerabilities. The code generation and exchange steps of the flow occur automatically by Zapier when enabled.
### Add Application Credentials to Zapier
* In your application's settings, you'll receive credentials that Zapier will use to verify itself to your app — typically called a *Client ID* and *Client Secret*, though they may have a slightly different name. Copy that data from your app, then in Step 3 of your Zapier OAuth configuration, paste those items in their respective fields. Zapier will use that data along with the authorization URL to receive the request token.
* Click *Save & Continue* to save your progress so far.
* Zapier automatically includes the Client ID and Secret in authentication API calls, but if you need to reference them in your integration's API calls or custom code, use the following codes: – Client Secret: `{{process.env.CLIENT_SECRET}}` – Client ID: `{{process.env.CLIENT_ID}}`
### Add OAuth Endpoint Configuration
* Add your application's Authorization URL, where Zapier will redirect users to authenticate with your app. Copy this URL from your application or integration settings where you copied the client ID and secret previously, or from your app's API page.
* By default, Zapier will pass the client ID, state, redirect URI, and a standard `code` response type as URL Params in the request to the authorization url. If you need to change that, click the *Show Options* button and add any additional call details needed.
> **Note**: The Oauth2 `state` param is a [standard security feature](https://auth0.com/docs/secure/attack-protection/state-parameters) that helps ensure that authorization requests are only coming from your servers. Most Oauth clients have support for this and will send back the `state` query param that the user brings to your app. The Zapier Platform performs this check and this required field cannot be disabled. The state parameter is automatically generated by Zapier in the background, and can be accessed at `bundle.inputData.state`. Since Zapier uses the `state` to verify that GET requests to your redirect URL truly come from your app, it needs to be generated by Zapier so that it can be validated later (once the user confirms that they'd like to grant Zapier permission to access their account in your app).
* To optionally limit Zapier's scope to let it only access specific data from your app, add OAuth scopes in the *Scope* field with a comma- or space-separated list.
* Add your app's Access Token Request URL from your API documentation, typically with a `POST` call.
* By default, Zapier will pass the client ID, client secret, authorization code, redirect URI, and a standard `authorization_code` grant type in the API request body with the access token request. If you need to change that, click the *Show Options* button and add any additional call details needed.
* If your API supports automated token refresh, add your API's Refresh Token Request URL, and check the *Automatically Refresh Token* box. This enables users' Zaps to run in the background without interruptions as long as possible by refreshing expired access tokens automatically.
* If your Access Token and Refresh Token requests don't return the tokens at the top level, use [Code Mode](/platform/build/code-mode) to modify the response so that the tokens are available at the top level. It is not possible to store an object with nested keys from the response.
* Zapier will automatically include the access token in subsequent API requests, but if you need to manually add it, the access token is stored in the `authData` bundle and can be referenced with `{{bundle.authData.access_token}}` or `{{bundle.authData.accessToken}}`, depending on how your API's response references the access token.
## 2. Add a Test API Request
* Add an API call to your API that requires no configuration, typically a `/user` or `/me` call. Add the URL for the API call, and set the call type, typically a `GET`. This will test the user-entered credentials to ensure it enables a successful API call to your app.
* The access token is included with the API call by default, as it will with all subsequent API calls, but if your API requires any additional configuration, click the *Show Options* button and add any options needed for a successful API call.
* To customize the test API request, select *Switch to Code Mode* and write custom JavaScript code to handle your test API call and the response parsing as needed. The first time you click the toggle, Zapier will [convert your API call to code](/platform/build/code-mode). If you switch back to Form Mode though, Zapier will not convert your code changes to the Form Mode, nor will any subsequent changes in the form be added to your code.
## 3. Configure a Connection Label
Review [connection label documentation](/platform/build/connection-label) to optionally differentiate the app accounts users connect.
## 4. Test your authentication
Connect a valid user account to [test authentication](/platform/build/test-auth).
## Video Tutorial
You can also refer to this video on implementing OAuth v2 in your Zapier integration:
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Zapier operating constraints
Source: https://docs.zapier.com/platform/build/operating-constraints
Zapier offers a relatively unique run-time environment for your integration and its requests to your API. The environment is stateless and restricts both execution time and payload size to offer normalized reliability and running time. There are three distinct contexts of this run-time that your integration will need to consider.
* Zap step setup and testing using the Zap editor
* Zap startup - turning a Zap on
* Zap step execution when a Zap runs
The following pages describe the operating constraints of these run-time modes, the errors your integration users could run into, and best practices. Developers in the Platform CLI development environment and those using [Code Mode](/platform/build/code-mode) in the Platform UI will find these pages most relevant.
Many errors can be viewed in your integration's log monitoring in the [Platform UI](/platform/build/test-monitoring), or if using the [Platform CLI](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#handling-throttled-requests), by using `zapier logs` command.
# Important Zapier constraints summary
| Time Limits | |
| ---------------------------------------------------------- | ---------- |
| Zap Editor test step: request(s) + scripting | 30 seconds |
| Polling trigger: request(s) + scripting | 30 seconds |
| REST Hook trigger: ingest and payload processing scripting | 30 seconds |
| Create/search action: requests(s) + scripting | 30 seconds |
| Size limits | |
| ---------------------------- | -------------------- |
| Deduplication table | 105,000 rows per Zap |
| Custom fields | 1000 |
| Webhook payload | 10 MB |
| Trigger/Action input payload | 6 MB |
| HTTP response payload | 20 MB |
| Downloaded files | \~120 MB |
| Throttles | |
| --------------------------------------------------------------------------------------------------------------- | --------------------------- |
| Polling trigger | Default: 100 new items/poll |
| REST Hook trigger | 10000 webhooks/5 minutes |
| | 30 webhooks/second |
| More on throttles [here.](https://help.zapier.com/hc/en-us/articles/8496181445261#h_01H91ED0PQ782E3B34ZRB5DXF7) | |
| TCP/IP | |
| ----------------------- | --------------------------------------------------------------------------------------------------- |
| Integration assigned IP | [AWS-East](https://zapier.com/help/troubleshoot/behavior/cant-access-or-use-zapier-with-other-apps) |
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Use pagination in triggers
Source: https://docs.zapier.com/platform/build/pagination-trigger
By default, Zapier triggers fetch new or recently updated data to start Zaps, and only need to find the most recently added items. Triggers can also be used to populate [dynamic dropdown fields](/platform/build/add-fields#dynamic-dropdown), and there they need to find all possible items to populate the field.
These triggers used for populating dynamic dropdown fields will often find dozens or hundreds of items. Many APIs let you split the results into pages. The first API call will return the first set of results — often 20 to 100. The items from this result would be seen as options in the dynamic dropdown field. If you want additional entries, you can make a new API call requesting page 2 and get the next set of results, iterating through the pages until the API has sent every possible option.
## 1. Enable pagination
* Log into the [Platform UI](https://zapier.com/app/developer).
* Select your **integration**.
* In the *Build* section in the left sidebar, click on the trigger that should power the dynamic dropdown field. This can be an existing trigger or a new trigger you set as *Hidden* if its only purpose is to power the dynamic dropdown.
* Go to the **API Configuration** tab
* In the **Configure your API Request** section, select the **Support Paging** checkbox, which should only be applied to triggers built to power dynamic dropdown menus. This enables Zapier's `bundle.meta.page` value which tracks the pages Zapier has loaded, along with a Load more option in the user-facing Zapier editor's dropdown menus.
* In the API Endpoint section, click *Show Options* to include `bundle.meta.page` in your API call as Zapier does not include that automatically, then add a new URL Param for your API's paging option (or optionally add it to your HTTP Headers if your API expects the paging value there). Use the page request field name from your API on the left, and `{{bundle.meta.page}}` on the right to have Zapier pull in the correct page value.
Note that Zapier's `bundle.meta.page` value uses zero-based numbering. The first time Zapier fetches data from your API, it uses a page value of 0, followed by 1 the second time, and so on. If your API expects the first API call to request page 1, with 2 for the second page and so on, you'll need to [switch to code mode](/platform/build/code-mode) and add `+ 1` to `bundle.meta.page`. So pagination in the code would look like the below (substituting `page` with the correct field name your API uses for pagination):
`'page': bundle.meta.page + 1`

* Test the API Request in the Platform UI and check the HTTP tab to see the request Zapier sent your app. Zapier should show a `page=0` value (or the correct term for pages in your API) under the Request Params header by default, or `page=1` if you're customizing the page requests to start at 1.
## 2. Test pagination
To test your paginating trigger:
* Build an action in the Platform UI that uses this trigger in a dynamic dropdown.
* Make a new Zap in the user-facing Zap editor that uses your action with the dynamic dropdown field. Click the dropdown field, scroll to the end, and click the **Load More** button. Repeat until it loads the last options, which will show a *We couldn't find any more choices* prompt.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Add a polling trigger
Source: https://docs.zapier.com/platform/build/polling-trigger
Set up your polling trigger in the Platform UI with the Settings, Input Designer and API Configuration tabs.
## Prerequisites
* Understanding of the [concept of deduplication](/platform/build/deduplication) and familiarity with how it is [explained to users](https://zapier.com/help/create/basics/data-deduplication-in-zaps)
## 1. Add the trigger settings
* Open the *Triggers* tab in Zapier's Platform UI and select **Add Trigger**.
* On the Settings page, specify the following:
– **Key**: A unique identifier for this trigger to be referenced inside Zapier. This is not shown to users. This cannot be edited once saved.
– **Name**: A human-friendly name for this trigger, typically with an adjective such as *New or Updated* followed by the name of the item that the trigger watches for inside your app. The title-case name is shown inside the Zap editor and on Zapier's app directory marketing pages.
– **Noun**: A single noun that describes what this trigger watches for, used by Zapier to auto-generate text in Zaps about your trigger.
– **Description**: A plain text sentence that describes what the trigger does and when it should be used. Shown inside the Zap editor and on Zapier's app directory marketing pages. Starts with the phrase “Triggers when”.
– **Visibility in Editor**: An option to select when this trigger will be shown. *Shown* is chosen by default. Choose `Hidden` if this trigger should not be shown to users. `Hidden` is usually selected when the trigger is not ready to be used in the integration, or for polling triggers that power [dynamic dropdown](/platform/build/add-fields#dynamic-dropdown) fields.
– **Directions** is used for [static webhooks](/platform/publish/integration-checks-reference#d017---static-hook-is-discouraged) only to describe how and where to copy-paste the static webhook URL for the trigger within your app. **Directions** will not show to users in other cases. Static webhooks are not permitted in public integrations.
* Click on the **Save and continue** button.
## 2. Complete the Input Designer
On the Input Designer page, add user [input fields](/platform/build/add-fields) needed by your API to watch for the triggering item.
Trigger input fields allow users to enter filters, tags, and other details to filter through new or updated data at the endpoint.
If no input data is needed for this trigger's endpoint, continue.
## 3. Set up the API Configuration
Platform UI selects a *Polling* trigger type by default.
Enter your API URL in the *API Endpoint* field. If your API URL requires specific data in the URL path, enter the following text in the URL where your API expects that data, replacing `key` with the input field key containing the relevant input field you created in the previous step:
`{{bundle.inputData.key}}`
Otherwise, Zapier will automatically include any input field data with the API call as URL parameters (for GET requests), or in the request body as JSON (for POST requests).
If your API requires any additional data to return the new or updated items in the [expected response type](/platform/build/response-types) of an array sorted in reverse chronological order, add it using the *Show Options* button to expose more detailed request configuration. Alternatively select *Switch to Code Mode* to [further customize the API call](/platform/build/code-mode) in JavaScript code.
Only if you plan to use this trigger to power dynamic dropdown menus in other Zap steps (such as to find users, projects, folders, and other app data often used to create new items), and if your API call can paginate data, select *Support Paging* (see [more details on dropdowns](/platform/build/add-fields#dynamic-dropdown) below).
Once you've added your trigger settings, click *Save API Request & Continue*.
## 4. Test your API request
Configure test data to [test the polling trigger](/platform/build/test-triggers-actions).
## 5. Define your output
Define sample data and output fields following [the guide](/platform/build/sample-data).
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Reduce requests to your API
Source: https://docs.zapier.com/platform/build/reduce-api-requests
## Trigger/action runs in a Zap
### Constraint
Each time a Zap runs and your integration is invoked, it can mean multiple requests to your API endpoints, depending on what your trigger/action seeks to accomplish. This can mean hundreds of requests/hour for your polling triggers based on a [Zapier customer's plan](https://zapier.com/pricing), or thousands based on a Zap with an active REST Hook Trigger from another app and an action in your app.
For triggers/actions that include files in the output, each time a Zap step requests a file from your API, it will be accessed and downloaded from the relevant endpoint.
### Best practice
One way to reduce that API load is via the Zapier platform [dehydration feature](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#dehydration). By putting any secondary requests behind a dehydration pointer, Zapier will only make this request once, although it might see the same records again and again based on the Zap's polling cycle.
For file outputs, implementing dehydration means the file will only be accessed and downloaded when a later Zap step asks for it.
To make this even more efficient, you can [stash the file](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#stashing-files) at Zapier. Rather than provide the file to the requesting step, Zapier will stash the file (under a dehydrated URL), so that only one request will ever be made for the file from your API.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Reorder or remove action
Source: https://docs.zapier.com/platform/build/reorder-action
Whenever a user selects your app's integration in a Zapier action step, they'll see every _create_ and _search_ action in your integration.
## Reordering actions
Zapier shows *create* actions first, followed by *search* actions. Within the Create and Search sections, actions are listed in alphabetical order and this order cannot be changed.
If you don't want an action to be shown, you can change the action's visibility at any time.
To change an actions's visibility:
1. Log into the [Platform UI](https://zapier.com/app/developer).
2. Select your **integration**.
3. In the *Build* section on the left sidebar, click **Actions**.
4. Click on the action whose visibility you wish to change.
5. Scroll to the bottom of the page to the **Visibility in Editor** and select `Hidden` if you want to keep users from being able to select the action
6. Users with that action selected in their existing Zaps would continue to be able to use it, but if they edit the Zap and select a different action, they will not be able to select the `Hidden` action again.
## Removing actions
You may want to remove an action your app no longer supports. Deleted actions cannot be restored.
If you remove an action from a live Zapier integration, this will break existing Zaps. As such, before removing an action, always [create a new major version](/platform/manage/versions) of your integration, hide the action in the new version, to allow users to [manually switch to a new action](/platform/manage/change-keys) without breaking their Zaps. Monitor integration usage by action from the Dashboard to only remove actions with no usage.
To remove an action:
1. Log into the [Platform UI](https://zapier.com/app/developer).
2. Select your **integration**.
3. In the *Build* section on the left sidebar, click **Actions**.
4. Click on the ellipses for the action you wish to remove, and click **Delete**.
5. On the confirmation prompt, click **Delete**
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Reorder or remove triggers
Source: https://docs.zapier.com/platform/build/reorder-trigger
Triggers are listed in alphabetical order in the Zap editor and this order cannot be changed.
## Reordering triggers
You can, however, change a trigger's visibility to control if it is shown to users or not.
To change a trigger's visibility:
1. Log into the [Platform UI](https://zapier.com/app/developer).
2. Select your **integration**.
3. In the *Build* section on the left sidebar, click **Triggers**.
4. Click on the trigger whose visibility you wish to change.
5. Scroll to the bottom of the page to the **Visibility in Editor** and select `Hidden` if you want to keep users from being able to select the trigger.
6. Users with that trigger selected in their existing Zaps would continue to be able to use it, but if they edit the Zap and select a different trigger, they will not be able to select the `Hidden` trigger again.
## Removing triggers
You may want to remove a trigger that your app no longer supports, or fully rebuild a new one in place of the previous one.
> Note: It is best practice to not remove a trigger that has been used in a live integration version. If a trigger is in use, it is recommended to [hide it rather than deleting it](/platform/manage/planning-changes#updates-to-triggeractionsearch-keys). Only remove unused triggers from staging or development versions.
To remove a trigger:
1. Log into the [Platform UI](https://zapier.com/app/developer).
2. Select your **integration**.
3. In the *Build* section on the left sidebar, click **Triggers**.
4. Click on the ellipses for the trigger you wish to remove, and click **Delete**.
5. On the confirmation prompt, click **Delete**
Deleted triggers cannot be restored.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Add authentication fields to Request Template
Source: https://docs.zapier.com/platform/build/requesttemplate
The Request Template is a request editor that lets users set static values that apply to all requests made by this integration. Users can configure the URL params, HTTP headers and request body. This is the perfect place to set authentication fields.
Adding input fields to the Authentication Fields also writes the fields to the Request Template.
By adding fields to the Request Template, they will also show up in the request builder of trigger and actions. The applicable fields for authorization in triggers and actions under Options would then be disabled with help text. You'll need to access the Request Template under Advanced Settings to make changes to them.
You can refer to this video on using Request Template:
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Response types Zapier expects
Source: https://docs.zapier.com/platform/build/response-types
With every API call, Zapier expects the response data to be returned in a specific response type. This can vary depending on what part of your integration you're working on. Use the table below to identify the correct response type to use
| Method | Response type | Notes |
| -------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Authentication** | Object | Single JSON-formatted object with any specific fields for auth scheme. |
| **Authentication testing** | Object | Object |
| **Trigger** | Array | JSON-formatted array with the results in reverse chronological order. Results are parsed and passed through [deduplication](/platform/build/deduplication). Empty arrays will not trigger. |
| **Create action** | Object | Individual fields within object are parsed for mapping into subsequent Zap steps. |
| **Search action** | Array | JSON-formatted array sorted with the best match first, but don't limit to a single result or group them as one. For no match found, return a `200` with an empty array. |
**Note**:
* If your app's API call does not return a response, Zapier will show a timeout error.
* If you use line items in your integration, note that not all Zapier integrations support line items. Use the recommended response type in the table to reduce users possibility of needing to reformat this data to use in their Zaps. Learn more on [how line items work in Zaps](https://help.zapier.com/hc/en-us/articles/8496277737997).
## Return related data as line items
Line items are used to present multiple items associated with a single transaction, such as an order or an invoice. To return line items in the data for your users in actions, you'll need to return the multiple items you want to show as an array of objects under a descriptive key.
For example, a Create Order action returning an order with multiple items might look like this:
```js
order = {
name: 'Zap Zaplar',
total_cost: 25.96,
items: [
{ name: 'Zapier T-Shirt', unit_price: 11.99, quantity: 3, line_amount: 35.97, category: 'shirts' },
{ name: 'Orange Widget', unit_price: 7.99, quantity: 10, line_amount: 79.90, category: 'widgets' },
{ name:'Stuff', unit_price: 2.99, quantity: 7, line_amount: 20.93, category: 'stuff' },
{ name: 'Allbird Shoes', unit_price: 2.99, quantity: 7, line_amount: 20.93, category: 'shoes' },
],
zip: 01002
}
```
## Return multiple items as search results
Do not use line items to group search results. Although Zaps only use the first result by default, users [*can* decide](https://help.zapier.com/hc/en-us/articles/8496241402253-Search-for-existing-data-in-Zaps) to group all results as [line items](https://help.zapier.com/hc/en-us/articles/8496277737997). Other products, like Agents, will always use all results. Do not group multiple results into line items — let products and users control that instead.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Output data, defining sample data and output fields
Source: https://docs.zapier.com/platform/build/sample-data
This guide will explain what output data, sample data and output fields are and how to modify them in your triggers or actions.
## Output data
Each Zap step must return data to Zapier to use in subsequent steps. By default, the output data is the direct response from your API—but in some cases, you may need to customize the response data to make it work well with Zapier. Here are general principles for output data from your Zap steps:
**Separate data where possible**, to make it as widely usable as possible in subsequent Zap steps. Names should be split into separate first/last or given/surname pairs, along optionally with a full name field. Addresses should be separated into their individual components.
**Format Date-time values in [ISO 8601](http://www.cl.cam.ac.uk/~mgk25/iso-time.html#date) standard including time zone offset**, even for UTC times. Avoid UNIX or Epoch timestamps. Date responses may be modified in your API call custom code if your API returns dates in different formats. Example acceptable date-time values include:
* `2023-12-15T01:15:13Z` (or `-0000` instead of `Z`)
* `2023-12-01T12:32:01-0800`
* `2023-12-01T12:32:01-08:00`
* `2023-12-13` (for date-only values)
**Optionally include an additional human-friendly date** especially for scheduling or calendar app integrations where the date is important for users.
**Set boolean values as `true` or `false`**. Do not use `1` and `0` for boolean values.
**Include the value name and ID in lists and dropdown menus** to help users know which item to choose.
**Consider removing non-necessary fields that may seem confusing to users** in your API call's custom code.
## Sample data
Sample data gives Zapier example data if users don't test the trigger or action. Though optional, it is especially important for triggers and also useful in actions.
In the Zap editor, Zapier will attempt to retrieve or create existing data to test triggers and actions. With triggers, Zapier will try to fetch recently added or updated items during the test. If the connected account doesn't have any data for this item (polling triggers) or the Perform List is not defined (REST Hook triggers), the user will see an error that no items are available.
Users can also opt to skip those test steps. In both cases, Zapier shows the sample data instead, to allow users to map fields correctly in subsequent Zap steps.
Sample data must be JSON-formatted and use the same field names as your app's API. Either click the *Use Response from Test Data* button to import the fields your app sent to Zapier in the previous test, or add your own JSON-formatted fields. No personally identifiable data should be included, and the copy must be safe for work.
Only include fields that are present every time a Zap runs. If a field is provided in the sample, it can be mapped into a field in a later action by any user.
If that mapped field is then not available when a user's Zap runs, the action field will be empty, causing errors or unexpected results for users. For example, suppose your sample data looks like this:
```JSON
{
"id": 1,
"first_name": "Jane",
"last_name": "Suarez",
"email_address": "janesz@example.com",
"job_title": "Executive Director"
}
```
A user might map the `job_title` information into a required field in another app, such as a CRM. Then, when the Zap runs, `job_title` is only included in the live result if it happens to be available, and the data the Zap receives looks like this:
```JSON
{
"id": 5,
"first_name": "Jacob",
"last_name": "Giotto",
"email_address": "jacob@example.com"
}
```
The user's Zap run will error when the request to the CRM's API attempts to add the person, because `job_title` is a required field in the CRM but there's no data in it. To avoid this, there are several [integration checks](/platform/publish/integration-checks-reference) that require sample and live Zap run data to match.
## Output fields
Output fields give your API's response data user-friendly labels in subsequent Zap steps.
By default, Zapier uses a basic human-friendly transformation of field names, capitalizing words and adding spaces instead of underscores. You can customize this further with Output Fields.
## How to modify your sample data and output fields
In your trigger or action settings:
1. Click *Step 3 Define your Output* to expand this section.
2. In the *Sample Data* field, add in your **JSON formatted sample data output**.
3. Click **Generate Output Field Definitions**.
4. In **Output fields** you'll see a table of fields with keys on the left, and field types on the right. Add a **human-friendly name** for each field in the center Label column, and select the **field type** in the right hand column.
5. Click **Save Output & Finish**.
For example, if you use GitHub's API to watch for new issues, the API calls the issue name `title`. Users may expect that field to be called *Issue* or *Issue Title*, so you could define the Output Field as having the name *Issue Title*, rather than the default transformation of “Title”.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Add a search action
Source: https://docs.zapier.com/platform/build/search
## 1. Add the action settings
* Open the *Actions* tab in Zapier's Platform UI from the sidebar on the left, and select **Add Action**, selecting your action type. New actions are *create* type by default, and add new data or update existing data to your app.
**Note**: You cannot change an action type once you click *Save and Continue* on a new action. If you need to change the action type, delete the action and recreate it.
* On the Settings page, specify the following:
– **Key**: A unique identifier for this action, used to reference the action inside Zapier. Does not need to be the same identifier as used in your API. Not shown to users.
– **Name**: A human friendly plain text name for this action, typically with a verb such as *Find* or *Search* followed by the name of the item this action will find in your app. The title-case name is shown in Zapier products and on Zapier's app directory marketing pages.
– **Noun**: A single noun that describes what this action searches, used by Zapier products to auto-generate text about your action.
– **Description**: A plain text sentence that describes what the action does and when it should be used. Shown inside Zapier products and on Zapier's app directory marketing pages. Start with the word “Find”.
– **Visibility Options**: An option to select when this action will be shown. *Shown* is chosen by default.
* At the bottom of the settings page, you'll see an option to pair your *search* with a *create* action. That lets your [action also create an item](/platform/build/search-or-create) if the search does not return any results.
* Click on the *Save and Continue* button.
## 2. Complete the Input Designer
On the *Input Designer* page, add user [input fields](/platform/build/add-fields) for this action. All action steps *must* include an input form for Zapier to gather the data needed to create or find items in your app. Add at least one input field to your action.
Before building your action's input form, list each piece of data your app needs to find an item. Most search actions only include a single input field, sometimes along with a drop-down menu to select filter data.
## 3. Set up the API Configuration
In the final *API Configuration* page, add the API endpoint where Zapier will send the search request to.
A `GET` call is used for search actions by default, and sends the data from the input form to your API endpoint.
Zapier expects an array response with 0 or more items.
If multiple matches are found, return a reasonable number of items. Pagination is not supported, and returning too many results will produce errors. Although by default Zaps only use the first result, users [*can* decide](https://help.zapier.com/hc/en-us/articles/8496241402253-Search-for-existing-data-in-Zaps) to group all results as [line items](https://help.zapier.com/hc/en-us/articles/8496277737997). Other products like Agents will always use all results. Do not group multiple results as line items yourself, as this will conflict with allowing products and users to control this.
If no matches are found, an empty array must be returned - even if the API responds with a `404` status. A *search* that returns no results is still considered a successful action step and [should not return an error](/platform/build/response-types).
If you need to parse the response from the endpoint into the expected response type, switch to [Code Mode](/platform/build/code-mode) to write custom JavaScript code for your action.
## 4. Test your API request
Configure test data to [test the *search* action](/platform/build/test-triggers-actions). Testing a GET request would be expected to return the item from the endpoint.
## 5. Define your output
Define sample data and output fields following [the guide](/platform/build/sample-data).
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Add a search or create action
Source: https://docs.zapier.com/platform/build/search-or-create
When adding a _search_ action type, you'll see the option to _Pair an existing search and a create to enable “Find or Create” functionality_ in the _Settings_ page. This embeds the _create_ inside the _search_ step to find or create items in one step of the Zap.
## Add a *create* action
* Add a relevant *create* action to your integration. If your *search* action is looking for contacts, say, you would need a *Add New Contact* action to pair with it. Open your integration's *Actions* page in a new tab and add a new *create* action if your integration does not have an appropriate one already.
## Configure the *search* action
* Back in your new *search* action's settings, check the *Pair an existing search and a create* box
* Select the relevant action from the *Create Action* menu and add a new label that Zapier will show on this step if users choose to have the action create new items as well.
* When users use the search action in a Zap, Zapier will show your core *search* action settings that you set in the *Input Designer* by default. Then, if users click the checkbox to create an item if nothing is found, Zapier will load the *create* action's input fields inside the search action so users can fill both out.
* Configure the rest of your search action as normal, including the [Test API Request](/platform/build/test-triggers-actions) and [Output](/platform/build/sample-data) sections.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Add authentication with Session Authentication
Source: https://docs.zapier.com/platform/build/sessionauth
Session authentication has elements of Basic authentication — where Zapier requests a username and password, and OAuth v2 — where Zapier redirects users to the app's site to allow access. User credentials are exchanged for a token used to authenticate subsequent API calls.
It is similar to cookie-based authentication in your browser, only here the “cookie” is an auth token stored by Zapier.
Use Session authentication with your Zapier integration if your API is designed for session-, cookie-, or token-based authentication.
## 1. Build an input form
* Open the *Authentication* tab in Zapier visual builder and select *Session Auth*.
* Session auth does not include any default input fields. Add the fields required by your API by selecting *Add Fields* and fill in the details for each field. Add the most commonly needed fields first, in the order users expect, as you cannot reorder fields once added.
* Two types of fields are available when building an Session input form. Standard Fields, work much like other form fields with Zapier's [input form](/platform/build/field-definitions) in triggers and actions. [Computed Fields](/platform/build/computed-fields) make sure specific fields are returned by your app's authentication API call response.
* For each field, add the required *Key*, the name your API uses to reference this field.
* Fill in the optional fields, as appropriate, especially the *Label*:
– **Label**: A human-friendly name for this field that will be shown to users in the authentication form.
– **Required? (checkbox)**: Check if this field is required for successful authentication.
– **Type**: All input fields use the `string` text field by default; select `password` instead if you would like to obscure the data as users enter it.
– **Help Text**: Include details to assist users in authenticating with your app, especially if they may be unsure where to find the data needed within your app. Format text with [Markdown](https://zapier.com/blog/beginner-ultimate-guide-markdown/), and include a hyperlink if needed.
– **Input Format**: (optional) Help users figure out exactly what piece of data you need them to enter. For example, for [a subdomain](/platform/build/subdomain-validation), [https://.yourdomain.com/](https://.yourdomain.com/).
– **Default Value**: Include a value for this field to be used as a fallback. For optional fields, the default value is set on initial connection creation and used in the API call instead of missing or null values every time the Zap runs. For required fields, this value is used during connection creation, but not when the Zap runs (Zapier raises an error for missing/null values instead).
* Input fields marked as password and all authentication fields with sensitive, private data such as both username and password from Session Auth are automatically censored at runtime. These values are stored in the Auth bundle and used in API calls, but are replaced in Zapier's logs with a censored value like this `:censored:6:82a3be9927:`. Due to this, it is not possible to view the exact tokens or keys in Zapier's logs. To verify that the same token as was returned by the authentication, is being used in subsequent API calls; you can compare censored value characters, for example `:censored:6:82a3be9927:` would have the same value ending in 9927 when used in a subsequent call.
* Each input field is listed with its label, key, type, and required status in your authentication settings. Click the field to edit it, or click the gear icon and select *Delete* to remove a field.
* For computed fields, available in OAuth v2 and Session Auth only, review [computed fields documentation](/platform/build/computed-fields).
## 2. Add a Token Exchange Request
* Add the token exchange request URL and select the HTTP method. Zapier will automatically include the data from the input fields in the API request body. If your API expects the data in the URL Params or HTTP headers instead, or requires additional data, click *Show Options* and add the details your API call needs. It is typically not recommended to pass any sensitive information such as the password in the URL Params. Passing it through the headers or the body is preferable.
* To customize the token exchange request, select *Switch to Code Mode* and write custom JavaScript code to handle the API call and the response parsing as needed. The first time you click the toggle, Zapier will [convert your API call to code](/platform/build/code-mode). If you switch back to Form Mode though, Zapier will not convert your code changes to the Form Mode, nor will any subsequent changes in the form be added to your code.
* If your token exchange request doesn't return the token and/or any [computed fields](/platform/build/computed-fields) at the top level, also use [Code Mode](/platform/build/code-mode) to modify the response so those fields are available at the top level. It is not possible to store an object with nested keys from the response.
* All values will be referenced via `{{bundle.authData.field}}`, where `field` is the key in the response.
## 3. Add a Test API Request
* Add an API call to your API that requires no configuration, typically a `/user` or `/me` call. Add the URL for the API call, and set the call type, typically a `GET`. This will test the user-entered credentials to ensure it enables a successful API call to your app.
* Session Auth doesn't include a defined standard for how access tokens are included in subsequent API calls, so unlike other authenticaton methods, Zapier doesn't include the access token by default. You'll need to add it in the test request and in subsequent Trigger and Action step API calls.
* Click *Show Options*, then add the access token to your API call's URL Params or HTTP Headers as needed. It is typically not recommended to pass any sensitive information such as the password in the URL Params. Passing it through the headers or the body is preferable. The Access Token will be in the `bundle.authData`, and typically be referenced as `{{bundle.authData.access_token}}`, `{{bundle.authData.sessionToken}}`, or a similar field, depending on how your token exchange response includes the token.
## 4. Configure a Connection Label
Review [connection label documentation](/platform/build/connection-label) to optionally differentiate the app accounts users connect.
## 5. Test your authentication
Connect a valid user account to [test authentication](/platform/build/test-auth).
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Enable static IP address connection for customers
Source: https://docs.zapier.com/platform/build/static-ip
To enable customers to access your integration by static IP address, all outbound traffic from Zapier to your integration will need to be routed through a smaller set of consistent IP addresses. Any app owner/developer can request to enable the static IP address feature on a private or public app.
## Traffic from Zapier
Traffic from Zapier uses the following IP addresses:
* 44.214.195.64/28 (us-east-1)
* 18.246.81.208/28 (us-west-2)
Enabling this feature will increase the volume of requests to your server received from these IP addresses. This means this change would affect all users of your integration who are on a Zapier Teams, Company, or Enterprise plan.
Review our documentation on how the [static IP address functions within Zapier](https://help.zapier.com/hc/en-us/articles/15406083674509-Use-a-static-IP-address-to-connect-to-Zapier).
## How to enable static IP address connection
1. **Consult with your Security team:** They can confirm if a static IP address is permitted within your network security policies and advise on any potential conflicts with existing security measures.
2. **[Contact Zapier Support](https://developer.zapier.com/contact)**: They can help you enable static IP addresses for any public or private app integration you are an [Admin](/platform/manage/add-team) for. The turnaround time is typically within 1 business day.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Validate domain and subdomain input fields during authentication
Source: https://docs.zapier.com/platform/build/subdomain-validation
When adding a subdomain input field, commonly used in OAuth implementations, additional validation is strongly recommended to prevent a potential security vulnerability. If not taken into account, an attacker could utilize a maliciously constructed subdomain field (like `attacker-domain.com/`) in order to redirect OAuth connection requests to that attacker-controlled domain (because `attacker-domain.com/.your-domain.com` resolves to the attacker's domain instead of the expected one). Taking the following steps prevents the potential for an attacker to access your integration's sensitive authentication information, such as the OAuth client ID or secret.
## Prerequisites
* An authentication method that uses pre-configured tokens or secret values (for example, OAuth 2)
* User is able to input a domain or subdomain when authenticating within Zapier
* Your integration stores sensitive authentication details (in environment variables, for example) which are used as part of the authentication process
## Steps
1. If your integration allows for the user to provide a domain, validate the input against an allow-list of trusted domains.
2. If your integration allows for the user to provide a subdomain, add conditional validation for the subdomain string whenever you include the value in your OAuth HTTP requests. This change will prevent potential exploitation of the subdomain vulnerability.
### Handle subdomain validation in Platform UI
* Update the *Access Token Request* and related sections under the *OAuth v2 Endpoint Configuration* options, using the [Code Mode](/platform/build/code-mode) editor.
* Example code for handling subdomain validation in integrations built using the Platform UI, via Code Mode:
```js
// --- UPDATE: add your validation for the subdomain field before using it ---
if (!/^[a-z0-9-]+$/.test(bundle.authData.yourSubdomainField)) {
throw new Error(
"Subdomain can only contain letters, numbers and dashes (-)."
);
}
const options = {
url: `https://${bundle.inputData.yourSubdomainField}.mydomain.com/oauth/access-token`,
method: 'POST',
json: {
'code': bundle.inputData.code,
'client_id': process.env.CLIENT_ID,
'client_secret': process.env.CLIENT_SECRET,
'grant_type': 'authorization_code',
},
}
return z.request(options)
.then((response) => {
const results = response.json;
return results.data;
});
```
### Handle subdomain validation in Platform CLI
* If you're using OAuth-based authentications, update the `getAccessToken` and optional `refreshAccessToken` configuration methods. If the integration uses [shorthand HTTP requests](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#shorthand-http-requests), switching to [manual HTTP requests](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#manual-http-requests) will allow you to perform this manual subdomain validation.
* Example code for handling subdomain validation in integrations built using the Platform CLI:
```js
const refreshAccessToken = async (z, bundle) => {
// --- UPDATE: add your validation for the subdomain field before using it ---
if (!/^[a-z0-9-]+$/.test(bundle.authData.yourSubdomainField)) {
throw new Error(
"Subdomain can only contain letters, numbers and dashes (-)."
);
}
const response = await z.request({
url: `https://${bundle.authData.yourSubdomainField}.mydomain.com/oauth/token`,
method: "POST",
body: {
client_id: process.env.CLIENT_ID,
client_secret: process.env.CLIENT_SECRET,
grant_type: "refresh_token",
refresh_token: bundle.authData.refresh_token,
redirect_uri: bundle.inputData.redirect_uri,
},
});
return {
access_token: response.data.access_token,
refresh_token: response.data.refresh_token,
};
};
```
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Test authentication
Source: https://docs.zapier.com/platform/build/test-auth
Testing a user's authentication is crucially important, as it is later used to test subsequent trigger and action steps when built.
## Prerequisites
* Completed authentication configuration with your app's authentication scheme
* Set of valid user credentials for your app - recommended to use a new account specifically for testing so you don't clutter your core app account with testing data.
## Steps
1. In the final *Test your Authentication* step, enter user credentials
2. Select *Test Authentication* to make the test API call you configured
3. Successful authentication shows a green check and a *Request Successful* message at the top of the dialog.
4. The *Response* tab shows the JSON data response from your API, with each field and its data listed.
5. The *Bundle* tab shows the data Zapier stores about your authentication. Values returned by the test API call are stored in the `inputData` [bundle](/platform/build/bundle#inputdata) and can be accessed by `{{bundle.inputData.field}}` where `field` is the field key from the API response, for use in the [connection label](/platform/build/connection-label) or trigger and action requests. However, responses from the test API call are not stored for subsequent requests in the case of OAuth v2 and session authentication unless you use [computed fields](/platform/build/computed-test-field).
6. The *HTTP* tab shows the full request details for each API call Zapier made during the test.
7. The *Console* tab shows any additional data your API calls logged in Zapier if you use custom code for any part of your authentication.
8. Check each tab to ensure the expected data came through - it is possible to have an unsuccessful API call come through as successful if your API returns a message without an HTTP error code. Check the Response to make sure it includes the data expected from this API call, and if anything is incorrect, check the HTTP tab to help diagnose where things went wrong.
9. Clean up and remove older testing accounts from your core Zapier account. Open your [Zapier *Connected Accounts*](https://zapier.com/app/connections) page, and find your app's name (you may need to use the search box or `CMD`+`F` (Mac) or `Ctrl`+`F` (PC)). Click the app name. Once on the app's connections page, identify the connection to remove and click the three dots, then *Delete*, and confirm the deletion. Repeat for each subsequent testing account you added to clean up your authentication list.
Then refresh your integration page in the Platform UI, and you'll only see the authentications that were not deleted.
10. A caveat of testing in the Platform UI is that tokens are not saved in the Zapier database, so if you are testing the access/refresh token mechanism, make sure to test in a Zap in your account to avoid connections expiring or being marked as invalid.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Test and monitor your integration in your Zapier account
Source: https://docs.zapier.com/platform/build/test-monitoring
Testing inside the Platform UI is crucial during the building process. To ensure users can benefit from your integration's features, it is equally crucial to test your integration within the Zap editor. This is the best way to notice details that might have been overlooked while building your integration.
## Prerequisites
* Completed build of your Zapier integration
* A [Zapier account](https://zapier.com/sign-up)
* If you haven't used Zapier before, you'll want to learn the basics in our [Zapier Getting Started Guide](https://zapier.com/learn/zapier-quick-start-guide/).
* Set of valid user credentials for your app - recommended to use a new account specifically for testing so you don't clutter your core app account with testing data.
## Steps
1. Create a Zap in the [Zap editor](https://zapier.com/app/editor/), selecting your app in the *Choose App* selector.
2. Your integration will show the name and logo set in *Integration Settings*, along with the integration's current version number and a *By Invite* tag. If your integration is a new version of an existing *Public* integration, look for the *Latest* tag, the latest version number and the *By Invite* tag to differentiate from existing, public integrations.
3. Check each of the following as you setup Zaps:
* **Authentication**: Does your app account successfully connect? Zapier will show any testing accounts you already added, but try adding a new account here for a complete test. To remove connected accounts, you can delete connections from [Apps/Custom integrations](/images/c97ff65c5857c3ebfeb302ffa8454867.webp).
* **Connection Label**: Does the Zap editor show the [expected connection label](/images/693c0b1c08dabf06ea515995eab636aa.webp) on the new account, with the info you set when building your integration?
* **Trigger and Action List**: Do you see every trigger and action included in your integration? Is each trigger and action's name and description accurate and grammatically correct?
* **Fields**: Do triggers and actions show the input fields you expect? Are their names and labels accurate and grammatically correct? Do any links or formatting in descriptions work correctly? Do drop-down fields or those with multiple selectors work correctly?
* **Output**: When you run a Zap trigger or action's test, does the step return the fields and data you expect in the correct format? Do triggers show the most recently added item from your app, and do searches return appropriate results?
* **Input**: Open your app, and check each item that Zapier actions added or updated for the correct format and expected appearance in your app.
* **Automation**: Turn on Zaps with each of your integration's triggers and actions. Do they run correctly when the data they watch for is added or updated in your app? You can check your [Zap History](https://zapier.com/app/history) to make sure Zaps ran as expected for triggering events. Do your integration's actions successfully add and update items when those Zaps are triggered?
## Monitoring
Use the *Monitoring* page in the Platform UI to ensure that test Zaps and the expected requests are running without errors. Every request made to your API by your Zapier integration is shown.
Adjust the Chart Filter for the correct timeframe, then click on any data point in the chart to see the any error messages and logs which should help you troubleshoot further. You can also filter by log type and by user email.
To manually print a log statement you can see in Monitoring, use `z.console.log` in Code Mode:
`z.console.log('Here are the input fields', bundle.inputData);`
You can also refer to this video on using the Monitoring tool:
## User testing
Have internal team members and/or beta users test your integration. If you are going to submit your app for *Publishing* in the Zapier App Directory, you'll need at least 3 users with live Zaps. Each additional tester helps ensure that your app doesn't ship with usability problems or bugs.
Internal team members can be invited from *[Manage Team](/platform/manage/add-team)* as admins or collaborators.
Beta users external to your organization can be invited from *[Sharing](/platform/manage/sharing)*
The *Insights* section in the Platform UI provides usage statistics by trigger and action.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Testing Tools
Source: https://docs.zapier.com/platform/build/test-tools
The Zapier platform provides a set of tools to help inform and validate your integration before pushing changes out to users.
## Canary Testing
Canary testing is a way to test new changes temporarily with real users in production with the goal of validating changes to ship new changes with more confidence and reducing bugs. These users are not informed or aware of the changes, as this is usually done at random and in small subsets to obtain a sample. Builders should have careful monitoring in place to watch for errors and rollback when necessary.
### Prerequisites
* Completed build of your Zapier integration, built from the CLI (as of Sep 23, 2024, this is a CLI only feature)
* If you haven't used Zapier before, you'll want to learn the basics in our [Zapier Getting Started Guide](https://zapier.com/learn/zapier-quick-start-guide/).
You may want to use the canary tool when adding a new feature, or fixing a bug. For example, if you are planning to roll out a bug fix, you may want to test this out to see if the fix will work. The usual validation steps may include unit tests, and [setting up Zaps for validation](/platform/build/test-monitoring). Unit tests will ensure your integration code functionality matches what you intended to do. Setting up Zaps will ensure the trigger or action works with the inputs you provide. The canary tool ensures your changes work for many existing live Zaps, with different inputs and outputs.
[`zapier canary`](https://github.com/zapier/zapier-platform/blob/main/packages/cli/docs/cli.md#canarycreate) provides a new way to validate your integration and build confidence that the change can work for all different types of Zap set ups.
[`zapier canary:create`](https://github.com/zapier/zapier-platform/blob/main/packages/cli/docs/cli.md#canarycreate) allows you to set the version you want to test with, the version you want to replace with, the percentage of traffic, and a duration before the versions are rolled back.
[`zapier canary:list`](https://github.com/zapier/zapier-platform/blob/main/packages/cli/docs/cli.md#canarylist) allows you to see the active canary and see how much time is left.
[`zapier canary:delete`](https://github.com/zapier/zapier-platform/blob/main/packages/cli/docs/cli.md#canarydelete) You can choose to delete the canary test before the duration is expired in case something unexpected occurs.
### Best Practices
* **Start Small**: Begin with a small percentage of traffic.
* **Monitor Closely**: Use monitoring tools to track performance and errors.
* **Communicate**: Inform your team about the canary test.
### Troubleshooting
* **Issue: High Error Rate**: Rollback immediately and investigate the logs.
* **Issue: Performance Degradation**: Reduce the traffic percentage or rollback.
### FAQ
A: The system will automatically rollback to the previous version after the specified duration.
A: Yes, you can extend the duration by stopping the existing canary, and re-running the `zapier canary` command with a new duration.
A: Use Zapier's monitoring tools and logs to keep track of the test performance. We don't currently have a way to isolate monitoring for canary, only the overall success or error pattern. Test
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Test triggers or actions
Source: https://docs.zapier.com/platform/build/test-triggers-actions
Once authentication is tested, trigger and action steps are easy to test inside Zapier visual builder. Set up the trigger or action settings and API calls, then as the last step the familiar _Test Your API Response_ box appears. It will show any accounts you added to your integration previously during the authentication testing.
## Prerequisites
* Completed authentication configuration with your app's authentication scheme
* Set of valid user credentials for your app - recommended to use a new account specifically for testing so you don't clutter your core app account with testing data.
* A successful authentication test
## Steps
1. Within *API Configuration* for each trigger or action, access the *Test your API Request* section
2. Fill in details for each of the input fields in the *Configure Test Data* form. Add data that will successfully work in this API call, similar to what you would use in a live Zap.
3. Enter individual values in each field to add single objects. If you include commas in the field data, Zapier will turn that field into an array sent to your API. Select *Raw* to preview the JSON formatted data.
4. Select *Test Your Request* to run the trigger or action step, verify it ran successfully and show the JSON results which you can explore as in the Authentication testing.
5. If an error is returned, check the following:
* Authentication: Did your app's authentication work correctly in the authentication step? You can only test an integration once you've connected an app account to Zapier.
* Test Data: Did your test data include the details your app expects, such as actual dates in date fields or complete email addresses in email address fields?
* Input Field Keys: Did you use the same field keys in your input field as your API expects? Double-check that in the Input Designer, and change if needed.
* API Call Customization: Does your API expect something different than the standard API call details Zapier sets by default? You may need to use Code Mode if the options you need aren't available.
6. When testing a [REST Hook trigger](/platform/build/hook-trigger), you will instead have to create and test a Zap in the Zap Editor as follows:
* Test the trigger to confirm that the Perform List works and provides live data from the app.
* Turn on the Zap to confirm that the subscription is successful.
* Perform the trigger event in the app to confirm that the webhook is sent to the Zap's webhook URL and triggers the Zap.
* Compare the data returned from the Perform (can be seen in the [Zap history](https://help.zapier.com/hc/en-us/articles/8496291148685-View-and-manage-your-Zap-history)) with the data returned from the Perform List and confirm that they are both in the same format and have the same information in them.
* Turn off the Zap to confirm that the unsubscription is successful. A successful unsubscription should delete the Zap's webhook URL from your app.
It is recommended that you check the logs in the [Monitoring](/platform/build/test-monitoring) component for feedback from your Zap testing.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Trigger
Source: https://docs.zapier.com/platform/build/trigger
Every Zap has a single trigger. Triggers are how your app's users can start automated workflows whenever an item is added or updated in your app. New or updated contacts, database records, blog posts, subscribers, form entries and project tasks, are examples of items that can be used to trigger a Zap.
Triggers only watch for new data and typically send no or little data to your app. They are often quicker to set up than Zapier [actions](/platform/build/action).
Design triggers around how users interact with your app, not based on which API endpoints are available.
The are two types of triggers.
## 1. Polling trigger
This trigger type periodically checks the provided API endpoint for new or updated data.
The update time or frequency of polling occurs per active Zap every 1 to 15 minutes, depending on the user's [Zapier plan level](https://zapier.com/app/pricing).
The API endpoint must list new or updated items in an array sorted in reverse chronological order. These are typically the most common API endpoints to read data from a platform. For new item triggers, the endpoint should list newly created items first; while for updated item triggers, recency of update is preferred. If your API lists items in a different order by default, but allows for sorting, include an order or sorting field in your API call to ensure newest records are returned on the [first page of results.](/platform/build/deduplication)
Include details in your trigger description to let users know which type of updates will run the trigger.
Zapier automatically deduplicates incoming polling trigger data, so that Zaps do not run multiple times on the same data. Known as deduplication, this is [explained to users as a concept](https://zapier.com/help/create/basics/data-deduplication-in-zaps). Ensure your polling triggers behave as users expect by following [deduplication guidelines](/platform/build/deduplication) for new item and updated item triggers.
## 2. REST Hook trigger
This trigger requires your app to support REST Hooks - webhook subscriptions that can be manipulated through a REST API. It runs in near realtime with your app pushing data to Zapier, running Zaps as soon as new data comes into your app instead of waiting for Zapier to fetch new data from your API on a polling frequency.
This method of triggering also prevents numerous - and sometimes unnecessary - requests from being made to your API's endpoints in polling requests.
A webhook subscription is created between Zapier and your app, and whenever the trigger event occurs in your app, a webhook is sent by your app to the unique webhook URL provided by Zapier for each active Zap started with that trigger.
Zapier supports immediate webhook handshake confirmations by echoing back the `X-Hook-Secret` header when present, but does not support additional identity verification steps beyond this.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Troubleshoot action request or response payload size
Source: https://docs.zapier.com/platform/build/troubleshoot-action-payload
## Testing action in Zap editor
### Constraint
When a user clicks **Test and Review** or **Retest and Review** in the Zap editor, the response payload must be less than 20MB.
### Errors user will see if constraint is hit
* *"Response payload size exceeded maximum allowed payload size"*
### Best practice
If your API endpoint supports request filtering, one option is to provide input fields in the action/search so a user can decide what record field data they want to return. If that is not available, you might look at having multiple endpoints for this record data. Your integration could then provide multiple action/searches for the user so they can get a full record.
## Action runs in a Zap
### Constraint
An action/search input payload must be less than 6 MB.
### Errors user will see if constraint is hit
* *"Invoke payload too large"*
### Best practice
Use the simplest available endpoint on your API for the basic record data, and use Zapier platform [dehydration](/platform/reference/cli-docs#dehydration) to request supplementary data from other endpoints. A dehydration pointer is created for each subsequent request, and this pointer will only be resolved if the Zap needs a hydrated property in a later step.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Troubleshoot action timeouts
Source: https://docs.zapier.com/platform/build/troubleshoot-action-timeouts
## Testing action in Zap editor
### Constraint
When a user clicks **Test and Review** or **Retest and Review** in the Zap editor, the output of your `perform` must be returned within 30 seconds.
### Errors user will see if constraint is hit
* *“The app did not respond in-time. It may or may not have completed successfully.”*
### Best practice
Timeouts can occur on your API endpoint, or within the `perform` method processing the response payload. To speed up the `perform`, check for expensive processing operations, and consider reducing `z.console.log` calls, especially in looping code.
## Action runs in a Zap
### Constraint
Each time a Zap step runs, the action/search's `perform` method must finish processing in 30 seconds. If the API request cannot consistently be finished within 30 seconds - for example, file format conversion, an error will show.
### Errors user will see if constraint is hit
* An error in the Zap history of their Zap due to the request timing out
### Best practice
For longer-running requests, use the webhook-based callback service the Zapier platform provides. This allows your action to be performed asynchronously, and when finished, POST to the callback URL. More on using this method [here](/platform/build-cli/core).
A user will then see the [Waiting/Delayed status](https://help.zapier.com/hc/en-us/articles/20505304170637-Review-Zap-run-statuses) in Zap history for that Zap step, until the POST is received to the callback url, upon which the task will resume.
***
[*Need help? Tell us about your problem and we'll connect you with the right resource or contact support.*](https://developer.zapier.com/contact)
# Troubleshoot custom fields
Source: https://docs.zapier.com/platform/build/troubleshoot-custom-fields
## Configuring the trigger/action in Zap editor
### Constraint
If your trigger, action, or search supports retrieving custom fields from your API, these are limited to 1000 custom fields, the output of the method to retrieve the fields must be returned within 30 seconds and the response payload must be less than 20MB.
### Errors user will see if constraint is hit
* Slow rendering of the step when it is added or edited in the Zap editor
* Custom fields might not display
* Not all output fields will be available for mapping in later steps
* *“The app did not respond in-time. It may or may not have completed successfully.”*
* *"Response payload size exceeded maximum allowed payload size"*
### Best practice
Here is an example of the way one integration works around all three of these constraints. [Hubspot](https://zapier.com/apps/hubspot/integrations) offers a CRM product, and users often have thousands of custom fields for Company records.
In the ***Create Company*** action, instead of presenting an overwhelming number of custom fields, they present a set of default fields that all companies have, then allow the user to select the other fields they might need from an ***Additional Properties to Retrieve*** dropdown menu field.
The fields chosen are then retrieved by the Zap editor for user editing. This helps in both making sure the request can be accomplished within the time and size limits, and making sure the user can easily find the custom fields important to their specific workflow.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Troubleshoot throttles
Source: https://docs.zapier.com/platform/build/troubleshoot-throttles
## Throttling by your API
### Constraint
Your API has request limits.
### Errors user will see if constraint is hit
* If a trigger, user will receive an email with an error message about the trigger error
* If an action, user will see an error in Zap history
### Best practice
Add a specific `Retry-After` header to your 429 response, or specify a timed delay in your error response using a special `ThrottledError`. Instead of a user's Zap erroring and halting, the request will be retried at the specified time.
More on the retry [here](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#handling-throttled-requests). The user will see a [Waiting/Scheduled](https://help.zapier.com/hc/en-us/articles/20505304170637-Review-Zap-run-statuses) message in Zap history instead of an error while the limit is still in place.
If implementing a `ThrottledError`, you could consider implementing a jitter for handling 429 errors, that could look something like this to randomize the frequency of the retries as well:
`throw new z.errors.ThrottledError('message here', 60 + Math.floor(Math.random() * 60))`
Keep in mind that adding custom error handling with `ThrottledError` would likely require a [new integration version](/platform/manage/versions), whereas adding to the headers could be implemented on your API's end.
## Webhook throttles by Zapier
### Constraint
Zapier's current webhook limits are [here](https://help.zapier.com/hc/en-us/articles/8496181445261#h_01H91ED0PQ56S166BSB7MJNZNT). A 429 response is returned if your integration exceeds these limits in number of webhooks sent to Zapier.
### Errors user will see if constraint is hit
* User will receive an email with an error message about the trigger error
### Best practice
You should support a retry/back-off schedule to make sure the data is eventually received.
## Polling trigger throttles by Zapier
### Constraint
There is a default limit of 100 new items recognized per poll after deduplication. More on that [here](https://help.zapier.com/hc/en-us/articles/8496181445261-Rate-limits-and-throttling-in-Zapier#h_01H91ED0PQ1HK1G1YFTZ9NSPRN).
### Errors user will see if constraint is hit
* The user will receive an email about held Zap runs, as well as a banner with the same information in their Zap history.
### Best practice
If your trigger will be returning > 100 new records consistently, consider converting your trigger to be REST Hook based. Webhook limits are higher (up to 10,000 requests in a 5 minute period).
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Troubleshoot trigger request or response payload sizes
Source: https://docs.zapier.com/platform/build/troubleshoot-trigger-payload
## Testing trigger in Zap editor
### Constraint
When a user clicks **Test Trigger** in the Zap editor, the input payload must be less than 6MB
### Errors user will see if constraint is hit
* *"Invoke payload too large"*
### Best practice
The Zap editor will only process three new records at a time for sample data, so one way of making sure your payload size is less than the limit is by limiting your results to three records.
To determine when the request is for sample data, use the bundle meta parameter `bundle.meta.isLoadingSample`. When that is set to `true`, the user is testing in the Zap editor, and your integration can respond with a limited payload. More on `bundle.meta` properties [here](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#bundlemeta).
## Turning Zap on
### Constraint
When a user toggles a Zap with a polling trigger “On”, Zapier does some additional initialization that must be accomplished in 30 seconds.
First, it tests the user's authentication to your service.
Then it uses the trigger's `perform` method to build a [deduplication table](/platform/build/deduplication) of records, so that the Zap will not run for existing records. The payload returned from this request must also be less than 20 MB.
### Errors user will see if constraint is hit
* Users will receive an email with an error message that includes the text *“Your Zap could not be turned on”*.
### Best practice
There is a `bundle.meta` property that you can take advantage of here, `bundle.meta.isPopulatingDedupe`. When set to `true`, the Zap is being enabled, and you can use that to create a distinct request. The deduplication process only uses the `id` property of each record, so one option to consider for this request is filtering the fields you return to reduce record size.
More on `bundle.meta` properties [here](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#bundlemeta).
For those requests that might otherwise exceed timeout or size limits, you can make sure your filtered request is successful. Alternatively, if your filtered request has a lot of headroom in both time and size, you could instead use this to load more records into the Zap's deduplication table than you usually request in your `perform`. This is especially relevant for an API that might return an inadvertent older record in a later polling request.
**Example:** The [Salesforce](https://zapier.com/apps/salesforce/integrations) integration has an ***Updated Field on Record*** trigger that can trigger on older records that a user might not consider relevant for their running Zap. To help mitigate this, the integration uses a filtered request to download up to 104,000 records to the deduplication table during Zap startup.
## Trigger runs in a Zap
### Constraint
Each time a Zap executes, the trigger's response payload must be less than 20MB for a polling trigger and less than 10 MB for a REST Hook trigger.
### Errors user will see if constraint is hit
* User will receive an email with an error message, usually with *“Trigger Partner Failure”* in the message text.
* The error may also contain *"Response payload size exceeded maximum allowed payload size"* in the message text.
### Best practice
* For polling triggers, if your API endpoint supports request filtering around number of records or datetime, using these to reduce the number of records returned
* If filtering isn't an option, consider using the simplest available endpoint on your API for the basic record data, and use Zapier platform [dehydration](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#dehydration) to request supplementary data. A dehydration pointer is created for each subsequent request, and this pointer will only be resolved if the Zap needs a hydrated property in a later step.
* For REST Hook triggers, if your REST Hook subscription endpoint supports filtering, one option is to provide input fields in the trigger so a user can decide what record data they want to return.
* Consider sending a notification REST Hook that includes minimal record data. You can then use additional API endpoints and Zapier platform [dehydration](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#dehydration) to request the supplementary record data. A dehydration pointer is created for each subsequent request, and this pointer will only be resolved if the Zap needs a hydrated property in a later step.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Troubleshoot trigger timeouts
Source: https://docs.zapier.com/platform/build/troubleshoot-trigger-timeouts
## Testing trigger in Zap editor
### Constraint
When a user clicks **Test Trigger** in the Zap editor, the output of your `perform` (polling) or `performList` (REST Hook) must be returned within 30 seconds.
### Errors user will see if constraint is hit
* *“The app did not respond in-time. It may or may not have completed successfully.”*
* *“Problem creating Sample: Our computers ran into a problem”*
* *“We couldn't find any more x. Create a new x in your account and try again.”*
### Best practice
The Zap editor will only process three new records at a time for sample data, so one way of speeding up the response is by limiting returned results to three records when a trigger is tested.
To determine when the request is for sample data, use the bundle meta parameter `bundle.meta.isLoadingSample`. When that is set to `true`, the user is testing in the Zap editor, and your integration can respond with a limited payload. More on `bundle.meta` properties [here](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#bundlemeta).
## Trigger runs in a Zap
### Constraint
Each time a Zap executes, the trigger's `perform` method must finish processing in 30 seconds. Polling triggers run on an interval based on a [user's Zapier plan](https://zapier.com/pricing) (between 1 and 15 minutes). REST Hook triggers run on an inbound POST to their subscription URL.
### Errors user will see if constraint is hit
* User will receive an email with an error message, usually with *“Trigger partner failure”* in the message text. An example of the email sent when the trigger errors due to a timeout:
### Best practices
* For polling triggers, if your API endpoint supports request filtering around number of records or datetime, use these to reduce the number of records returned
* For both types of triggers, optimize the `perform` scripting for manipulating the payload
* Use [console logging](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#console-logging) efficiently. It can help you determine where issues might lie, but too much console logging can cause timeouts due to logging overhead.
* If you have multiple requests per record that are causing timeouts, use the Zapier platform [dehydration functions](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#dehydration). Instead of making the request immediately, a dehydration pointer is created, and the request will only be made if the Zap needs a hydrated property in a later step.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Developer Platform Login
Source: https://docs.zapier.com/platform/dev-platform-login
# Powered by Zapier Documentation
Source: https://docs.zapier.com/platform/embed/powered-by-zapier
Powered by Zapier is the easiest ways to embed Zapier and surface integrations within your product.
Check out the [Powered by Zapier documentation](/powered-by-zapier/getting-started) to learn about [plug-and-play elements](/powered-by-zapier/integration-marketplace/low-code/workflow-element), the [Workflow API](/powered-by-zapier/api-reference/authentication), [quick account creation](/built-in-workflows/code-native/retrieving-a-list-of-zaps), and more.
Powered by Zapier is available for public integrations. To take advantage of our embed solution, first ensure your integration has been published to [Zapier's App Directory](https://zapier.com/apps). If your integration isn't yet published, learn more about [submitting your integration for review](/platform/publish/public-integration#4-submit-your-integration-for-app-review).
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Welcome
Source: https://docs.zapier.com/platform/home
### Explore our guides and start building a Zapier integration today
Welcome to the Zapier Developer Platform documentation! Whether you are a new or experienced integration builder, this is your go-to resource for learning how to create and manage powerful apps on the Zapier platform.
### What You'll Find Here
* **Getting Started**: Learn the basics of building integrations, from understanding Zapier's architecture to setting up your first app using the **Visual Builder** or **CLI**.
* **Visual Builder Guide**: If you're looking for a fast, no-code way to integrate your app with Zapier, the Visual Builder is the place to start. It's ideal for quick deployment and collaboration across teams, even without developer expertise.
* **CLI Guide**: For more complex needs, dive into the **Zapier CLI**, which gives developers full control over the integration process, using custom code to handle authentication, triggers, actions, and searches.
* **Best Practices**: Guidance on how to optimize your integrations for performance, user experience, and maintainability.
* **Advanced Features**: Explore OAuth authentication, dynamic dropdowns, and other advanced options to provide a more customized experience in your integration.
* **Deployment and Testing**: Once your integration is ready, follow the steps for deploying, testing, and promoting your app version to Zapier's marketplace of over 1 million users.
### Why Build on Zapier?
* **Reach Millions of Users**: By integrating with Zapier, your app becomes part of a thriving ecosystem that connects with thousands of other services.
* **Save Time with Automation**: Zapier simplifies repetitive tasks, letting your users focus on what matters most by automating workflows across tools.
* **Fast and Flexible**: Use the Visual Builder for quick, no-code setups or the CLI for full control and customization.
### Quick Links
* [Getting Started Tutorial](https://zapier.com/resources/guides/quick-start)
* [Zapier Developer Platform](https://developer.zapier.com/)
* [CLI Documentation](https://docs.zapier.com/platform/reference/cli-docs)
Ready to dive in? Choose your path—start building with the Visual Builder or master the CLI for complete customization.
# Active users retention
Source: https://docs.zapier.com/platform/manage/active-users
At Zapier, churn means a user used your integration in their Zaps 29 - 56 days ago, but hasn't run a successful task in one of those Zaps in the past 28 days. This user is considered to have churned from the integration. Maybe they switched to using a competing integration or their workflow had a more periodic or seasonal cadence.
But, it could also mean they got so frustrated with the experience of trying to get their Zap working and *keep* it working successfully - they turned it off, deleted it, and walked away.
Active users are the percentage of users who haven't churned.
## Key Zapier insights
Lowered active user retention rates don't necessarily mean poor integration health. Some apps lend themselves to use-cases with shorter lifespans than others. That said, spikes in churn rate not related to seasonal variations in usage could be indicators of a problem with something not functioning as expected.
Active user retention is not a leading indicator. In fact, it's quite a lagging one that may only start indicating a problem up to 28 days after it has been an issue. That doesn't deem it useless, we just have to know how to make full use of it.
## Best practices
Approaching active user retention with a long-term strategy can help maintain a consistently high level of retention:
* [Embed](https://platform.zapier.com/embed/overview) the Zapier experience with copy-and-paste and customizable code within your platform to provide automation value directly to users. Embeds have proven to [reduce churn](https://platform.zapier.com/partner_success_stories/all) on Partners' platforms. Learn about embedding options in the [guide](https://learn.zapier.com/surface-your-zapier-integration-within-your-app).
* [Share use cases](/platform/publish/partner-faq#tip-4-share-zapier-use-cases-in-your-onboarding) widely during your platform's onboarding process. Having multiple Zaps using your integration increases stickiness of users not only to the Zapier integration, but also to your platform.
* Update the integration regularly with features as your platform evolves. [Invite stakeholders to your integration](/platform/manage/add-team) to give them admin or read-only access to insights, metrics, and feedback to prioritize and align improvements.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Invite team members to your integration
Source: https://docs.zapier.com/platform/manage/add-team
Integrations do not have a dedicated owner, instead they are managed by a team that can be modified as needed. Add team members to your integration to collaborate, contribute, and view analytics data for your integration on the Developer Platform. Your integration team can have up to 200 team members, regardless of whether your integration is Private or Public.
Team members added to your integration will be assigned one of the following roles:
* **Admin**: Admins are granted read and write access to the integration. This role is ideal for developers and individuals actively involved in building and maintaining the integration.
* **Collaborator**: Collaborators are granted read-only access to the integration. Collaborator access is recommended for product, leadership, partnership, marketing, and other teams seeking access to integration data for analysis and record-keeping without direct involvement in its creation and maintenance. While they cannot make direct changes to the integration, they can:
* View performance data
* View the integration history
* Review and comment on feature requests and bug reports
* Access tools to embed your integration throughout your site to drive user adoption
## Invite team members
To add team members to your integration, follow these steps:
1. Log into the [Developer Platform](https://zapier.com/app/developer)
2. Choose your integration
3. In the *Manage* section on the left sidebar, select *Manage Team*
4. Select *Invite Team Member*
5. Enter the email address of the team member that you want to invite
6. Select the role that you wish to assign to the team member
7. A note will be included in the invitation email. You can either use the default message provided, or customize it with your own text
8. Click *Send Invite*.
**Note**: Admins can invite both Admins and Collaborators, while Collaborators can only invite Collaborators.
Once you click *Send Invite*, an email invitation will be sent to the invitee, requesting their acceptance. If the invitee does not already have a Zapier account associated with the invited email, they will need to create an account first. Upon accepting the invitation, they will gain access to the integration through their Zapier account on the Developer Platform.
## Self-serve Collaborator access
Depending on your [integration settings](https://cdn.zappy.app/b2637f3ad910c36c4e8c8224c349beee.png), users have the option to self-serve and join an integration team as Collaborators. This feature employs domain-name verification and is managed by integration Admins. Currently, this feature is only available for integrations listed in [Zapier's directory](https://zapier.com/apps).
### Enable or disable self-serve Collaborator access
To toggle the “Join an Integration as Collaborators” feature, please follow these steps:
1. Log into the [Developer Platform](https://zapier.com/app/developer)
2. Choose your integration
3. In the *Manage* section on the left sidebar, select *Manage Team*
4. Select *Settings*
5. Click the toggle to enable or disable self-serve join as Collaborator
### Manage eligible email domains for self-serve Collaborator access
1. Log into the [Developer Platform](https://zapier.com/app/developer)
2. Choose your integration
3. In the *Manage* section on the left sidebar, select *Manage Team*
4. Select *Settings*
5. Click “Edit email domains”
6. Add/remove the domain(s) to be allowed
### Join an integration team via self-serve Collaborator access
1. Log into the [Developer Platform](https://zapier.com/app/developer)
2. Click “Get Access” under Join an Integration as Collaborators
3. Search for and select your integration, then click “Submit”
4. If the Zapier account you're using is associated with an approved domain, you'll receive an invitation to join via email
## View and remove team members
You can view a list of invited team members (both accepted and pending invites) from the *Manage Team* page. Admins have the ability to remove team members (both other Admins and Collaborators) from this page. Collaborators can only remove other Collaborators. You can also remove yourself from the team, regardless of your role. It's important to note that if you are removed as an Admin, you can regain Admin access only if invited by an existing Admin.
## Assign marketing and technical contacts
Admins have the ability to assign dedicated marketing and technical contacts on the integration team. Assigning these contacts allows us to better streamline outbound communication, and ensures the right contacts receive timely information. Please note that Zapier's support teams might reach out to the technical contact for technical support. E.g. we might contact this person so we can collaborate on trickier Customer Support tickets on Zaps that involve your integration.
### How to assign contacts
1. Navigate to the “Manage team” page in the developer platform
2. Click the “Settings” icon for the user you want to assign a role to
3. Click either “Set marketing contact” or “Set technical contact”
4. Users will be tagged with the role they are assigned
### Notes
* Each integration team can have only one designated marketing contact and one designated technical contact at a time
* A single user can be labelled as both the technical and marketing contact, they do not need to be separate users
* Users are not alerted when they are assigned or removed from a role
* Only Admins can assign roles, Collaborators cannot assign roles
* You can manually remove a role from a user by clicking the “Settings” icon and selecting “Revoke technical contact” or “Revoke marketing contact”
* You do not need to remove a role from a user before assigning the role to another user
* Assigning a role to a new user that's already been assigned to another user will cause the role to automatically be removed from the original user
* Only integration team members that have accepted a role can be assigned a role (ie team members that are Invitation Pending cannot be assigned a role)
* The user assigned as the marketing contact will be shown as the contact on private invite sharing pages
## Manage email subscriptions relating to your integration
### General marketing updates
Zapier sends out general partner marketing updates related to your integrations and the Developer Platform. These emails include:
* Monthly Partner Newsletter with integration data insights
* Outreach about partnership and co-marketing opportunities
To control your subscription for these emails, visit the [email preferences page](https://developer.zapier.com/partner-settings/email) in the developer dashboard and opt in or out per each integration you are a team member of.
### Platform and Partner Program updates
All members of your integration's team will also receive Zapier Platform and Partner Program Updates. These emails include:
* Alerts about user [Bugs and Feature Requests](/platform/manage/integration-insights)
* Critical Platform and Program Updates
You cannot unsubscribe from Zapier Platform and Partner Program Updates unless an existing integration team member removes you from the integration team entirely. These emails deliver essential announcements about the Partner Program, Zapier Platform features, product updates, and compliance with integration quality standards to ensure you're always up-to-date with changes that could impact your use of the Zapier Platform.
**Note: An Admin can remove another Admin or Collaborator from the integration team. A Collaborator can only remove other Collaborators from the integration team.**
### Opting team members into emails
If you want to ensure that your team members receive partner marketing emails:
1. [Invite your team members](/platform/manage/add-team) to the integration team as either an Admin or Collaborator and ensure they accept the invite.
2. Team members who accept the invite will automatically receive Platform and Partner Program Updates.
3. If they want to receive General Partner Marketing updates, have them visit their [email preferences](https://developer.zapier.com/partner-settings/email) in the developer platform and ensure they're opted into emails for the integration you want them to receive alerts for.
## Video Tutorial
You can refer to this video on managing integration team members:
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# null
Source: https://docs.zapier.com/platform/manage/api-outage
Zapier recognizes that temporary unavailability is sometimes inevitable for your API.
To accommodate these situations, we recommend configuring [custom error response handling](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#general-errors) to:
* Present a meaningful, user-friendly message to users
* Refrain from disabling Zaps due to error-ratios
* Potentially reattempt the action after a given delay window
## 1. Default behavior
Zap runs that encounter a 5xx error from your API throw an exception and receive the “Stopped / Errored” status. This will [display an error message to the user](https://help.zapier.com/hc/en-us/articles/20505304170637-Review-Zap-run-statuses); allowing them to replay the Run.
If the user has [Autoreplay](https://help.zapier.com/hc/en-us/articles/8496241726989-Replay-failed-Zap-runs#how-autoreplay-works-0-4) enabled, then the errored steps will be retried on [a defined schedule](https://help.zapier.com/hc/en-us/articles/8496241726989-Replay-failed-Zap-runs#how-autoreplay-works-0-4). Only when all Autoreplay attempts have also failed will the Zap Run be assigned the “Stopped / Errored” status.
If [95% of a Zap's runs in the last 7 days are assigned the “Stopped / Errored” status](https://help.zapier.com/hc/en-us/articles/8496037690637-Troubleshoot-errors-in-Zapier#500-series-error-codes-0-3), the Zap will be paused automatically. The Zap will not run again until the user manually enables it.
## 2. Avoid automatic Zap disablement
### Platform CLI
When building in the [CLI](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md), you can [make use of HTTP middleware](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#using-http-middleware) to implement [custom error response handling](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#error-handling).
This allows you to write a single script that applies across the entire integration to detect a specific error from the API, and act accordingly. For example, if the API's outage duration is known, you could catch 503 responses during the `afterResponse` middleware and throw a [`ThrottledError`](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#handling-throttled-requests) like this:
```js
const yourAfterResponse = (resp) => {
if (resp.status === 503) {
throw new z.errors.ThrottledError('Service is temporarily unavailable. Retrying in 60 seconds.', 60); // Zapier will retry in 60 seconds
}
return resp;
};
```
> **Note:** You need to set [`skipThrowForStatus`](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#http-response-object) to `true` when invoking `z.request()`.
### Platform UI
When building in the [UI](https://developer.zapier.com/), custom error handling needs to be added to each individual element of the integration (authentication, triggers, actions) using [Code Mode](/platform/build/code-mode).
For example:
```js
const options = {
url: `https://example.app/api/endpoint`,
skipThrowForStatus: true,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
params: {},
body: {}
}
return z.request(options)
.then((response) => {
if (response.status === 503){
throw new z.errors.ThrottledError('Service is temporarily unavailable. Retrying in 60 seconds.', 60); // Zapier will retry in 60 seconds
}
const results = response.json;
return results;
});
```
> **Note:** Integrations built with the Zapier Platform UI can enable the *skipThrowForStatus* toggle under [Advanced/Settings](/platform/build/errors) to On to use [`skipThrowForStatus:true`](https://cdn.zappy.app/8ac6af91f6b27c4a473d566f1534b27e.png) on every request
## 3. Specify how long Zapier should wait before retrying
The `ThrottledError(message,delay)` method accepts two input parameters; a custom error message (string) and a delay expressed in seconds (integer).
Include a Retry-After header with responses provided by your API during downtime, to specify the amount of time until the service is expected to be back online and Zapier should retry the request. Your [custom error handling script](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#error-response-handling) can read this header and pass it to the delay parameter for `ThrottledError()`, like this:
```js
if(response.status === 503){
const delay = response.getHeader('retry-after');
const message = `Service is temporarily unavailable. Retrying in ${delay} seconds.`;
throw new z.errors.ThrottledError(message,delay);
}
```
## 4. Scheduled API maintenance
For periods of scheduled maintenance, a status of an app (API) as “unhealthy” can be set between a specific start and end time on request. A “Scheduled Maintenance” message will then be posted to our [status page](https://status.zapier.com) for [example](https://status.zapier.com/incidents/njgw7lrhn5hs).
The app will also have a status of “unhealthy” on the [*App Status* tab.](https://status.zapier.com/#app-status)
During a set maintenance window, Zaps impacted by the downtime will be affected as follows:
**Actions/Searches:** Zap runs with affected actions/searches will have the status of “Playing” in the Zap History page. The action/search will be delayed until the incident resolves, or up to five times. On the fifth time, Zapier will attempt it regardless of the app status. If it fails, Zap runs will error and [normal manual replay mechanisms](https://help.zapier.com/hc/en-us/articles/8496241726989-Replay-failed-Zap-runs) can be used to try to replay any affected Zap runs.
**Triggers:** *most* Zaps with affected (polling) triggers won't run and so (for the most part) there will be no Zap runs in [Zap History](https://help.zapier.com/hc/en-us/articles/8496291148685-View-and-manage-your-Zap-history).
In more detail, Zapier will “skip” 90% of polls, allowing 10% through, so typically *some* runs will occur for *some* Zaps. After 15 minutes, all polling is re-enabled to check if the API is healthy again. If not, Zapier will again “skip” 90% of polls. This will be repeated until the API is healthy. Once the API is healthy, Zaps will be triggered and “catch up” on missed data, subject to normal polling limitations such as [pagination](/platform/build/trigger#how-to-use-pagination).
If Zap runs error users will be notified via email based on their [notification settings](https://help.zapier.com/hc/en-us/articles/8496289225229-Manage-notifications-when-errors-occur-in-Zaps).
If you would like to schedule a maintenance window for your app, please send across the following information to [Developer Support](https://developer.zapier.com/contact)
* Start date and time (in UTC)
* End date and time (in UTC)
* Further details about how the API will respond during the downtime if called; eg. will it return an [HTTP 503](https://www.webfx.com/web-development/glossary/http-status-codes/what-is-a-503-status-code/) “Service Unavailable” status code or not respond at all.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Change authentication field keys
Source: https://docs.zapier.com/platform/manage/auth-keys
## Change scenario
You want to change the key of one or more [authentication input fields](/platform/build/basicauth#1-build-an-input-form) required when a user authenticates your app to Zapier.
## Impact to users
This is a **breaking change**.
Modifying the key of an existing authentication field constitutes a breaking change. Without adequate precautions, existing app connections may break as [migration](/platform/manage/migrate) is not possible. Users will need to establish a new connection to your integration and manually refresh each of their Zaps.
## Best practices
We strongly encourage you to **avoid changing authentication field keys** whenever possible.
### Workaround
If your API endpoint requires a different property for authentication, think about adjusting the property key rather than amending the form field input's key. This modification must be made in each trigger, action, search request, as well as in the authentication.
> NOTE: Form field input keys do not need to match directly with the properties your API expects.
For example, let's say you have a form field input with the key `API-KEY`and are sending the field's value to your API using the same property name of `API-KEY`.
```bash
headers: {
"API-KEY": bundle.authData.api_key; // original
}
```
Next, your API changes and expects the request property to be `X-API-KEY` instead. You can change the request property key (left) as needed. But still refer to the original form field input (right).
```bash
headers: {
"X-API-KEY": bundle.authData.api_key; // new - request key and field key can differ
}
```
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Add required authentication field
Source: https://docs.zapier.com/platform/manage/auth-required
## Change scenario
You'd like to add, remove, or change an optional input field to be required in your current authentication schema.
## Impact to users
This will cause a breaking change which will have the following significant effects to users:
* Existing connected accounts will not work: All existing connected accounts will no longer be functional with your integration until users re-authenticate manually.
* Manual updates are required for all Zaps: Zaps cannot be migrated due to a breaking change, users will have to edit each Zap individually before they can start running tasks again. For example, if a user has 20 Zaps set up with your integration, they will need to manually update each one of those Zaps.
## Best practices
* **Add the field as optional:** Use field \[help text]\(/ and [custom error handling](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#error-handling) (if you're using our Code Mode or the CLI platform) to validate that the newly required field is provided, while keeping it set to optional. Also, consider using custom code to set the field's default value in your API call if left blank.
* **Set a default value:** If possible, provide a default value for the required field that can be overwritten if necessary. This ensures that users who do not provide explicit values for these fields can continue to use your integration without issues.
For example in the case of updated API endpoints for geographical region or site domain, it is possible to account for an added **required** inputField with scripting to ensure existing authentications are backward compatible, allowing existing users to be migrated to the new version.
In this example code, the default URL for US region is updated when the user selects AU or CA when authenticating.
```js
let baseURL = "theUsApiBaseUrl";
switch (authData.region) {
case "AU":
baseURL = "theAuApiBaseUrl";
break;
case "CA":
//other regions can be easily supported by adding cases like this
baseURL = "theCaApiBaseUrl";
break;
default:
console.log("Legacy credentials are in use, defaulting to US Base URL.");
}
```
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Change authentication type
Source: https://docs.zapier.com/platform/manage/auth-scheme
If your API's authentication method changes, you would need to change the method Zapier uses to authenticate user accounts.
## Impact to users
Changing the authentication type (e.g., Basic Auth, API Key, or OAuth) of an integration is regarded as a breaking change. Notably, migration is impracticable since all pre-existing connected accounts would stop working if migrated. Users would need to make a new connection to your integration and manually modify each of their Zaps.
However, if your integration meets the following conditions, you can use the [contact form](https://developer.zapier.com/contact) to request support for migrating connected accounts between authentication types:
1. Your integration is public.
2. You have an API endpoint or can otherwise programmatically exchange data of the old type (e.g. an API key) for the new type (e.g. an OAuth2 access and refresh token).
3. The API endpoints that the integration actions use, can work with both the old and new auth type, at least for a few months until the old type may be sunset.
4. Exchanging e.g. an API key for an OAuth2 access token doesn't immediately invalidate the API key, and thus break other connected accounts that may still use it.
## Best practices
**Creating a New Version**
* [Clone](/platform/manage/clone) your app, generating a new version.
* [Remove](/platform/build/auth#how-to-remove-or-change-zapier-integration-authentication-scheme) the existing authentication method and incorporate the new one.
* Once configured, [promote](/platform/manage/promote) this version, making it available for new users to select during the connection of your integration to Zapier.
**Managing Existing Users**
* If users with existing authentications can retain their connection using the old method, enabling them to stick to the old version is recommended.
* However, they will be prompted to form a new connection for any new Zaps since only the promoted version is available during a name-based app search.
**Deprecating legacy authentication scheme**
* If existing authentications are set to be non-functional in the future, then [Deprecation](/platform/manage/deprecate) is required.
* Be mindful that this can be notably disruptive for our mutual users and thus should be considered carefully.
> NOTE: this method is not possible with apps built in the legacy web builder. To update the authentication, you would need to update all triggers/actions/searches as well; as deleting the authentication method and re-adding it in the new builder would not be compatible with existing triggers/actions/searches built in the legacy web builder.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Change OAuth scope
Source: https://docs.zapier.com/platform/manage/auth-scope
How to add or remove OAuth scopes.
## Impact to users
When an action in a new version of your integration requires additional OAuth scopes, there is no way around asking users to reconnect existing connected accounts before they can use the new action.
You can remove scopes only if no actions need it anymore. Note that existing connected accounts may still have been granted the scopes, and will only lose them when they get reconnected.
## Best practices
Follow these steps to provide the best user experience when adding new scopes.
1. In the new version where you need the additional scopes, try using the action with a existing connected account, and use [error handling](/platform/build/errors) to ensure that the error message instructs users to reconnect the account.
2. In the new version, add the required scopes to the *Scope* field [in the UI](/platform/build/oauth#add-oauth-endpoint-configuration) or `scope` [in the CLI](https://github.com/zapier/zapier-platform/blob/main/packages/schema/docs/build/schema.md#authenticationoauth2configschema).
You may need to select the scopes for the OAuth client used by the integration as well, in order for us to be able to request them.
3. Verify that the action now works by connecting an account using the new version.
4. [Promote](/platform/manage/promote) the new version.
5. [Migrate](/platform/manage/migrate) 100% of users to the new version.
The last two steps are critical to enable users to adopt the new scopes by reconnecting existing connected accounts.
# Changes to your API can impact your integration
Source: https://docs.zapier.com/platform/manage/change-api
## Change scenario
When making changes to your API, consider how these will affect your Zapier integration. API updates can vary from small to significant changes and can have varying effects on your users' Zaps.
## Impact to users
Though not exhaustive, here are some potential major impacts to users:
* If a new version with breaking changes to authentication is promoted, users with existing Zaps will have to manually reconnect their account on Zapier.
* If a new version with breaking changes to any trigger, action, or search is promoted, users with existing Zaps will have to manually upgrade *each* Zap using your integration. Keep in mind: power users can have tens to hundreds of Zaps using your integration.
* Changes to a trigger, action, or search's response data can break or negatively affect the proceeding steps of the Zap.
* Changes to response data in polling triggers can prevent Zaps from triggering on new records or cause them to trigger on old records. This can lead to missed data and undesirable results for your users.
## Best practices
To mitigate the impact of API changes on your Zapier users, consider the following best practices:
* Maintain general backwards compatibility on existing endpoints. This ensures that the existing Zaps continue to work as expected, and your users won't need to modify them due to API changes.
* For polling triggers - changing the number of records returned from the endpoint can significantly impact the functionality of the users' Zaps.
* Implementing pagination on an endpoint can affect how much data is fetched and processed when a Zap polls that endpoint.
* Changing the sort order of response data returned can impact Zap triggers. For polling triggers, ensure that the data is always sorted in reverse chronological order to maintain compatibility.
By adhering to these best practices, you can minimize disruptions to your Zapier users when updating or modifying your API. A well-managed API transition process ensures that your users continue to have a seamless and efficient Zapier integration experience.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Change trigger or action key
Source: https://docs.zapier.com/platform/manage/change-keys
## Change scenario
In cases where a trigger/action/search's custom code needs to be rewritten or a new v2 is replacing an older v1.
## Impact to users
Deleting a trigger/action/search in a new version is a breaking change - which would prevent migration of your users to the new version. Updating an existing trigger/action/search's custom code would allow for migration but break users' Zaps if the output changes.
The triggers, actions, and searches are identified by their **key**, such as `new_contact` or `create_post`, so if you remove that key from the app's definition, or change it (possible in CLI apps only), this message appears when you attempt to migrate.
## Best practices
* If you have already renamed the **key** (possible in CLI apps only) for a trigger/action/search, you'll need to switch it back to the previous **key** to proceed with migrating users.
* If you need to remove a trigger/action/search, change its visibility to **hidden** instead. Use the Visibility Options dropdown in the [UI](https://platform.zapier.com/polling-trigger#1-add-the-trigger-settings), or the `hidden` key in the [CLI](https://github.com/zapier/zapier-platform/blob/main/packages/schema/docs/build/schema.md#basicdisplayschema).
Migrated Zaps that used the hidden trigger/action/search will now show it as Deprecated in the Zap editor, but will continue to function as long as the endpoints remain valid.
Once a user selects a different trigger/action/search when editing their Zap, they will not be able to retrieve the hidden one. New users will not see any `hidden` trigger/action/search as available for selection.
* If you need to add a new trigger/action/search that replaces the hidden one, create a duplicate and give it a new **key** (such as appending `_v2` on the end), and keep the Name and Description the same if the functionality for a user is the same.
* This way existing Zaps continue to work once migrated with the previous (and now hidden) definition, and new Zaps will only be able to select the new definition.
* In cases where the endpoint in the hidden trigger/action/search will be sunset and begin to return errors in the future, the impact to users would be as follows:
Once the API has been sunset, active Zaps (turned on) using the impacted trigger/action/search will produce errors when they run. Depending on [user's email notification settings](https://help.zapier.com/hc/en-us/articles/8496289225229), owners of these Zaps will be sent email notifications about these errors.
If those Zaps exceed the error ratio **and** users have not [overridden related settings in their Zaps](https://help.zapier.com/hc/en-us/articles/8496037690637-Troubleshoot-errors-in-Zapier#i-want-my-zap-to-continue-running-even-when-there-are-errors--0-6), those Zaps will be automatically turned off.
* If you'd like to add custom errors within Zapier for the hidden trigger/action/search at the time of the endpoint sunset, you could consider the following:
Create a new version of the integration that immediately throws a `z.errors.Error` exception in the `perform` method of the impacted trigger/action/search. Learn more for apps maintained in the [UI](/platform/manage/planning-changes#custom-error-handling-in-the-ui) or the [CLI](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#zerrors).
*Promote* and then *migrate* users to this new version as close to the sunset date as possible.
The benefits of this approach are:
* Throwing an explicit exception will ensure impacted Zaps will hit the error ratio (and be turned off) at the earliest possible time.
* You can add a user-friendly message to the exception that users will see in both Zaps Runs on the [Zap History](https://help.zapier.com/hc/en-us/articles/8496291148685-View-and-manage-your-Zap-history) and also in email error notifications, e.g. *This function has been deprecated and is no longer available.*
* Here's an example of how a custom error message would be displayed on an action in the Zap History:
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Update perform method for polling trigger
Source: https://docs.zapier.com/platform/manage/change-perform
## Change scenario
It is generally safe to update a polling trigger's [perform method](https://github.com/zapier/zapier-platform/blob/main/packages/schema/docs/build/schema.md#basicpollingoperationschema) (Platform CLI) or [API Configuration](/platform/build/polling-trigger) (Platform UI), as long as the changes maintain backward compatibility in the returned response data. This means that the output fields and output data structure should remain consistent with previous version's.
## Impact to users
Updating a polling trigger's perform method or API Configuration might cause deduplication issues and cause old records to trigger a Zap if any of the following changes occur:
* The [primary key](/platform/build/deduplication) (usually an `id` field) is changed or removed from the API response.
* The perform method's endpoint is modified, resulting in fundamental changes to the primary key value.
For example, if the API or endpoint previously returned dedupe IDs as integers -1,2,3,4 - and is now updated to return alphanumeric values - 1-abc, 2-bcd, 3-cde, 4-def - records that were previously processed will fire again since the new IDs aren't saved in the deduplication table that Zapier references during each poll.
## Best practices
* Ensure the primary key remains unchanged: If the API response changes the primary key, use [custom code](/platform/build/deduplication#custom-primary-keys) to maintain consistency and prevent deduplication issues.
* Maintain reverse chronological order: the trigger should continue to return data in reverse chronological order to prevent unintended records triggering the Zap.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Change trigger from polling to REST Hook
Source: https://docs.zapier.com/platform/manage/change-trigger
## Change scenario
Your app needs to change how it notifies Zapier of new records - changing the type of trigger - from Zapier polling an app endpoint for new items to instead a REST Hook subscription where the app notifies Zapier of new records; or vice versa.
## Impact to users
This is a breaking change. Edits to an existing trigger's type will cause your users' Zaps to stop working and they would need to create new Zaps with the new trigger type, and manually re-create their actions. Using the [Duplicate feature](https://help.zapier.com/hc/en-us/articles/15408145778829-Duplicate-your-Zap) would help, but each Zap would need to be mapped individually with the new trigger.
## Best practices
* Copy the trigger configuration into a new trigger and give it a new **key** (such as appending `_v2` on the end), change the type for this new trigger, and **hide** the previous trigger. This way existing Zaps continue to work with the previous (and now hidden) trigger definition, and new Zaps will use the new trigger definition.
* This is the recommended path forward whether using the Platform UI or the Platform CLI, with the only difference being using the *Visibility: Hidden* toggle in the UI and setting the `hidden` key as `true` [in the CLI](https://github.com/zapier/zapier-platform/blob/main/packages/schema/docs/build/schema.md#basicdisplayschema).
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Clone a version
Source: https://docs.zapier.com/platform/manage/clone
Cloning allows you to duplicate an existing version of your integration. This is particularly useful when you want to introduce new features or fixes without altering the original integration. When a previous version of your integration has more than 5 active users, you will need to clone that version to make modifications.
> **Note**: The term “cloning” is specific to the Platform UI and is not used with Platform CLI. However, the concept is similar to updating the version number in your `package.json` file and running [`zapier push`](https://github.com/zapier/zapier-platform/blob/main/packages/cli/docs/cli.md#push) to create a new version you can access within your Zaps for testing.
## How to clone an integration version
1. Log into the [Platform UI](https://zapier.com/app/developer).
2. Select your **integration**.
3. In the *Manage* section in the left sidebar, click **Versions**.
4. On your existing version, click the **three dots icon**
5. From the dropdown menu, select **Clone**.
6. The *Clone Version* dialog box will appear. In the dropdown field, select which **version** you want to clone your existing version too.
* **Patch (e.g., 1.0.0 to 1.0.1)**: Ideal for backward-compatible changes such as bug fixes or updating help text.
* **Minor (e.g., 1.0.0 to 1.1.0)**: Use this for adding new functionalities that do not disrupt existing features, like creating a new trigger or action.
* **Major (e.g., 1.0.0 to 2.0.0)**: Choose this option for changes that are likely to break existing Zaps, like removing triggers or actions, altering authentication methods, or revamping the entire integration.
7. Click **Clone**.
8. A dialog box will appear confirming you've cloned your version.
Now you can make edits and improvements to your integration.
## Video Tutorial
You can refer to this video on cloning an integration version:
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Deprecate or delete a version
Source: https://docs.zapier.com/platform/manage/deprecate
Deprecation is an optional process that allows you to set a date from which an integration version cannot be used anymore. Zapier is normally a “set it and forget it” experience for users, so use this feature carefully. Only if the version will no longer function, should it be deprecated. Please note that deprecating a version is significantly disruptive to our mutual users if a migration to a different version is not possible.
When users use any but the promoted version, they will [see the version displayed](https://help.zapier.com/hc/en-us/articles/18755649454989-App-versions-in-Zapier) and be able to manually update to the promoted version.
## What happens after setting a version to deprecate
The deprecation date must be between 3 weeks and 1 year in the future. We won't communicate the deprecation until 2 weeks before the deprecation date. This gives you time to migrate users to a newer version, before we start notifying them that they need to manually migrate.
### 1. Email notification
A notification email will be sent exactly 14 days before the configured deprecation date. This email includes the deprecation reason that newer versions of the Zapier CLI ask you for. We do recommend supplementing these automated messages by also notifying your general user base through in-app announcements or email marketing campaigns. For privacy reasons, Zapier cannot provide you with an email list of users of your integration.
### 2. Deprecation date reached
* Zaps that haven't been updated will be automatically paused.
* A second email, titled “X Zaps paused over deprecated apps,” will be sent out to those users. Customizing this email is not possible.
* Any attempts to test triggers or actions on the deprecated version will result in an error, and Zaps that use it cannot be enabled.
* The deprecated version will be labelled as “Deprecated” in the Zap editor, with a prompt for users to update to the latest version.
### 3. Post-deprecation
After the deprecation date, the version will still be visible in the Versions page for your future reference. Users will not be able to see the version once they select a different version in their Zaps.
## Deprecate a version with Platform UI
To deprecate an integration version:
1. Log into the [Platform UI](https://zapier.com/app/developer).
2. Select your **integration**.
3. In the *Manage* section in the left sidebar, click **Version**.
4. Click the **three dot** icon in line with the integration version you want to deprecate.
5. Click **Deprecate**.
6. In the dialog box, add the **Deprecation Reason** and **Deprecation Date**. You can set a deprecation date anytime between 3 weeks and 1 year from the current date. The deprecation reason will be used in user notifications.
7. Click **Deprecate**.
8. Click **Close**
## Deprecate a version with Platform CLI
To deprecate an integration version use the command `zapier deprecate`. Learn more about [Platform CLI commands](https://github.com/zapier/zapier-platform/blob/main/packages/cli/docs/cli.md#deprecate).
## Deleting deprecated versions
After your version has been deprecated, you have the option to delete versions entirely. Exercise this option with extreme caution. Deleting a version makes it permanently inaccessible, both to you and to your users. Deleted versions cannot be restored by Zapier Developer Support. Deletion should be a last resort, used only when you are certain that the version will never be needed again.
Deletion is also only possible when 0 users remain on a version. The count of users on the *Versions* page includes live Zaps only. If you're seeing the error `Unable to delete app version`, this can be caused by users on that version not included in the visible count (paused Zaps, app authentications for example).

***
### **We’re no longer supporting our integration and would like to remove it from the app listing. How can I unpublish the integration and deactivate it?**
For any public integration, the first step is to revert that integration to private, which will prevent new users from seeing it in the Zapier App Directory or in the Zap editor.
Once the integration is private, you can deprecate each version of that app (except the latest version, which will remain private if there are users still on the version). to deprecate an integration version, please follow the steps outlined above.
If the product's API endpoints will be shutdown, any users still using that now-private app in their Zaps, will begin to see errors when requests are made to those endpoints and their Zaps will eventually be turned off, no longer making requests.
That said, if you want to proceed with this, please reach out to Developer Support and we’ll help you revert your integration to private so that you can proceed with the next steps.
[*Need help? Tell us about your problem and we'll connect you with the right resource or contact support.*](https://developer.zapier.com/contact)
# Embed activation rates
Source: https://docs.zapier.com/platform/manage/embed-activation
Consider all the user clicks on Zap Templates surfaced in your embeds. The embed activation rate is the percentage of those Zaps that actually activated within 24 hours of creation, meaning the Zap ran at least one successful task. It measures the efefctiveness of the Zapier embeds in your product at converting user clicks on Zap Templates to Zap activations.
In your integration's *Insights*, along with activation rate, see a funnel-view of users who signed up for Zapier, created Zaps, enabled Zaps, and activated Zaps from Zap Templates in your embeds.
A low activation doesn't necessarily mean something is broken. Both your integration and embed(s) could be implemented correctly and in good health, but you could still be seeing low activation rates. Embed insights can help identify where in their journey users are hitting challenges with activating, whether it's the Zapier sign up, Zap setup or enablement stage.
## Key Zapier insights
Embed insights and activation rates are strong indicators of user awareness and integration usability. If the click-to-sign-up ratio is really low, perhaps you haven't set sufficient context and expectations where the embed is placed for users to feel confident when they land on Zapier.com. If the create-to-enabled ratio is low, users could be having trouble with authenticating or field mapping once they're in the Zap editor creating a Zap from the template.
## Best practices
* If there are no *Embed insights* in your Dashboard, there are no embeds associated with the integration. Check out the *Embed* tab of your integration's Dashboard or our [Powered by Zapier](https://zapier.com/l/partner/solutions) documentation to see how you can start embedding. Embed features are only available for public integrations.
* We offer a variety of [embed tools](https://platform.zapier.com/embed/overview) as different options work best for different Partners and their platforms. Implement a combination of our partner tools and compare metrics to see which implementations are most successful for your use case.
* Users are more likely to sign-up when they are aware of Zapier and the value we provide by integrating to your app. Give context of Zapier via a brief onboarding flow or link to help docs so users know what to expect.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Embed insights definitions
Source: https://docs.zapier.com/platform/manage/embed-insights
Embed features are available for public integrations.
All metrics can be filtered by *All Embeds* or [individual embeds](https://cdn.zappy.app/195883ab4fd7897224bcec00b7bf9b13.png), and the [last 7, 30, and 90 days](https://cdn.zappy.app/e3d334462ad532540710a7ce0d975942.png), hover over the metric to see the percentage and count figures.
Definitions for each of the metrics provided in the integration dashboard below:
| **Metric** | Definition |
| -------------------------------------- | ---------------------------------------------------------------------------- |
| **Total conversion** | Percentage of users who clicked on Zap Templates and activated a Zap. |
| **Users who clicked on Zap Templates** | Percentage and count of users who clicked on a Zap Template in an embed. |
| **Users who signed up for Zapier** | Percentage and count of users who signed up for a new account on Zapier. |
| **Users who created Zaps** | Percentage and count of users who started a Zap in the editor. |
| **Users who enabled Zaps** | Percentage and count of users who created and successfully published a Zap. |
| **Users who activated Zaps** | Percentage and count of users who created a Zap that successfully ran tasks. |
## Best practices
* Test different iterations of embeds and compare rates to see which ones resonate most with your users. Do certain sets of Zap Templates garner more clicks and activations than others? Does enabling “App search” on the Full Zapier Experience, so users can see all the apps they can integrate with, increase activations?
* Improve your Zap Templates with short, descriptive titles, and as much [prefilled field mapping](https://platform.zapier.com/embed/zap-editor#prefill-options) as possible, so users are immediately aware of the use case and can activate the Zap with the least amount of clicks.
* Provide context with your embed through help docs or an onboarding flow guiding users on how to connect your app with others using Zapier to improve the *Users who signed up for Zapier* rate.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Improve error response handling
Source: https://docs.zapier.com/platform/manage/error-handling
Errors from your API cause pain for users at two vital points:
* During the Zap setup process, stopping them from enabling and activating their Zaps
* During the Zap's runtime, once it has been turned on, preventing the Zap from completing all actions successfully
Zap runs that encounter an error response status code when making a request to your API throw an exception and receive the “Stopped / Errored” status. This will [display an error message to the user](https://help.zapier.com/hc/en-us/articles/20505304170637-Review-Zap-run-statuses) in their Zap History and they will be notified via email based on their [notification settings](https://help.zapier.com/hc/en-us/articles/8496289225229-Manage-notifications-when-errors-occur-in-Zaps).
Even if the `message` included in the response details an error, users should **never receive** a success/200 response if there was an error in the request as this will not show up as an error in the Zap history.
If [95% of a Zap's runs in the last 7 days are assigned the “Stopped / Errored” status](https://help.zapier.com/hc/en-us/articles/8496037690637-Troubleshoot-errors-in-Zapier#500-series-error-codes-0-3), the Zap will be automatically turned off. The Zap will not run again until the user manually enables it, so only return an error if the scenario is truly an error that needs to be fixed.
Monitor spikes in errors from the the *Monitoring* page in the Platform UI as leading indicators of problems users are facing within your integration.
The more descriptive and thorough [error handling](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#error-handling) your API and integration have in place, the easier it will be for users to resolve their own issues and for Zapier's support team to assist with debugging.
If you don't have control to make changes to the API itself, utilize custom error handling to improve your error messages:
* Elaborate on briefly worded errors with user-friendly messaging.
* When writing user-facing error messages however, keep the message below 250 characters total as Zapier truncates errors from integrations at 250 characters when displaying them to users.
* Update “not\_authenticated” to “Your API Key is invalid. Please reconnect your account.”
* Surface specific information to users regarding the field and why it's producing an error. This empowers users to fix Zap issues independently.
* Instead of “Provided data is invalid”, return “Contact name is invalid”.
* Improve “Contact name is invalid” with “Contact name exceeds character limit.”
* Format the error to include a second, optional argument code machines can use to identify the type of error, and last, optional argument of a HTTP status code. `throw new z.errors.Error('Contact name exceeds character limit.', 'InvalidData', 400);`
Your app integration can use custom code to improve the user experience in Zapier by returning a user-friendly message and optional error and status code. Typically, this will be prettifying 4xx responses or APIs that return errors as 200s with a payload that describes the error. The code and status is used by Zapier to provide relevant troubleshooting to the user when communicating the error.
## Prerequisites
* Documentation for the API you're working with that includes the response status codes per endpoint
* Familiarity with [general error handling in Zapier](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#general-errors).
## 1. Custom errors in Platform CLI
Switching to the [Platform CLI](/platform/manage/export-cli), allows you to [make use of HTTP middleware](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#using-http-middleware) to implement any [custom error response handling](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#error-response-handling).
This will allow you to write a single script that applies across the entire integration to detect a specific error from the API, and show the relevant message to the user within Zapier.
## 2. Custom errors in Platform UI
When you build and maintain your app in the UI, custom error handling can still be implemented. The main difference is that you'll need to add it to each individual element of the integration (triggers, actions, searches, authentication) that could encounter the error.
In the UI, `skipThrowForStatus` is set from the [Advanced tab](/platform/build/errors). This allows for custom error handling for status codes above 400. Note that 401 status codes will throw a `RefreshAuthError` [regardless](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#user-content-error-response-handling).
Once set, you can add [error handling](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#general-errors) when in Code Mode within the API Configuration for each trigger/action/search.
```js
return z.request(options).then((response) => {
if (response.status === 404) {
throw new z.errors.Error(
"An error was returned. Help!",
"InvalidData",
404
);
}
return response.json;
});
```
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Essential tips for integrating quality health practices
Source: https://docs.zapier.com/platform/manage/essential-tips-iq
Our shared customers rely on Zapier and your integration for business-critical workflows. Addressing feedback early and often ensures users have the best experience, both with Zapier's platform and yours. Follow these tips on how.
## 1. Embrace early bug resolution
Early bug resolution prevents minor issues from escalating into significant problems, ensuring your users have a smooth and reliable experience.
## 2. Prioritize user-requested features
Requests for new features are invaluable insights into your user needs and pain points. Prioritizing these requests in your development roadmap can help enhance the functionality of your integration and significantly boost user retention and loyalty.
> Pro tip: Explore users' most valued and widely used features per app category! Head over to our [must-have triggers and actions](/platform/quickstart/must-have-triggers-and-actions) page for details.
## 3. Make Zapier an integral part of your product strategy
Your integration is a powerful tool for automating workflow, increasing productivity, and providing value to your users. Including it in your product expansion strategy and product roadmap planning, ensures it evolves in tandem with your core offerings.
> Pro tip: Read on how you can [prioritize user feedback](https://zapier.com/blog/prioritize-user-feedback-with-beamer/) in your product roadmap planning.
## 4. Spread the word about your integration's new features
Highlight new features and enhancements to your integration in your marketing materials. Adding these to newsletters, blogs, and in-product messages (IPMs), can help drive engagement and encourage users to explore new functionalities, leading to increased adoption and deeper integration into their daily workflows.
> Pro Tip: Get your integration in front of more users by embedding [Powered by Zapier](https://zapier.com/partner/solutions/plug-and-play) directly into your product.
## 5. Keep your integration fresh with regular updates
Regular updates signal to your users that you are committed to continuously improving their experience. Establish a cadence for updates that align with your sprint cycles.
> Pro tip: Add them to your calendar.
**Next Steps:**
* Actively monitor user feedback
* [Leave a comment](/platform/manage/user-feedback) on the Bugs & Feature Requests section inside your Partner Dashboard
* When promoting a version, link any open bug reports and feature requests that the newly promoted version addresses
* *Only possible when promoting within the Platform UI*
* Leverage [Quick Account Creation](https://platform.zapier.com/embed/quick-account-creation) to ease user signup friction and enhance security, through your embed placement
* Make staying on top of your open bugs and feature requests a priority by leveraging [Zapier Issue Manager](/platform/manage/user-feedback#3-consider-zapier-issue-manager)
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Export integration to Platform CLI
Source: https://docs.zapier.com/platform/manage/export-cli
The Zapier Platform CLI (Command Line Interface) is a toolset you install and run in your local development environment. It allows you to build, test, and manage your Zapier integration through JavaScript code and terminal commands.
Platform UI is the way for users with API experience that are more comfortable with a visual form editor to build integrations on Zapier.
The CLI is, on the other hand, the most powerful tool for professional developers and teams. Some of the advantages:
* Access to all [features](/platform/quickstart/ui-vs-cli) of the Zapier Platform
* Ability to better optimize your code. Move shared logic into modules. Leverage middleware to centralize request & response processing.
* Easier team collaboration. You'll be able to check all the code for your Zapier integration into your team's source control repo.
* Set up automated regression tests, to catch errors each time you push a change.
To export your existing Platform UI integration to Platform CLI:
## 1. Install and configure the Zapier CLI on your development environment
Follow the steps in the setup section in our [quickstart guide](/platform/reference/cli-docs#quick-setup-guide)
## 2. Run the `convert` command to create a CLI version of your project locally
Create a new directory for your Zapier project and from the command line `cd` into it. Then run:
`zapier convert {your integration id} . --version={integration version you want to convert}`
Your integration ID can be found in the browser location bar in the Platform UI:
Similarly, your version can be found there, and elsewhere throughout the Platform UI:
Using this example, to create our project in the current directory our command would be:
`zapier convert 1234 . --version=1.0.0`
## 3. Explore your new CLI project and get familiar with the tool
Check out the resources available in the [CLI section](/platform/reference/cli-docs) of the docs to learn all about the Zapier CLI.
If you need a refresher on JavaScript, it's well worth the time to check out some of the many great resources available [online](https://javascript.info/). The Zapier Platform uses promises pretty heavily, so this is a good JavaScript topic to get familiar with.
## 4. Deploy
When you ran convert and created your new local CLI project, it was automatically associated with your Zapier integration (using the `.zapierapprc` file).
A couple of important notes before deploying:
* When you push the CLI project to the server it will create a *new version* of your integration. If you haven't gotten familiar with how versions work you might take a moment and learn about those [here](/platform/manage/versions).
* Take a look at the version number in your `package.json` file. When you created your project with the `convert` tool we automatically incremented the version you converted. You can change this to a different version number depending on your needs, but make sure a version with that number doesn't already exist in your integration. Run `zapier versions` from your project directory to see what's already been created.
* Integrations converted with the `zapier convert` command will include `convertedByCLIVersion` in the `package.json` for informational purposes.
When you're ready to deploy your CLI version run:
`zapier push`
When that completes you'll be able to see the new version in the Platform UI in the Manage > Versions section, and will be able to make Zaps with your new CLI-built version.
You will not be able to edit your new CLI-built version from the *Build* section of the Platform UI, the attributes of this version will all [show a lock icon](https://cdn.zappy.app/f048ffc4c905bcbb332e344ce0ce52ba.png).
You can still use all the other functions of the Platform UI, though, including version management, embed management and your Partner Dashboard. Your earlier versions, created within the Platform UI, are also still available and can still be edited and used.
If you decide that the Platform CLI is not for you, you can delete your new version from Manage > Versions and continue where you left off in the Platform UI.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Export integration to Platform UI
Source: https://docs.zapier.com/platform/manage/export-ui
The Zapier Platform UI is the easiest way for anyone with API experience to build Zapier integrations. It is for users more comfortable with a visual form editor.
Some advanced calls and response parsing can still be performed in the Platform UI when using [Code Mode](/platform/build/code-mode).
The Platform UI has the following advantages over the CLI:
* A graphic user-interface with form-based editor.
* A live form preview that shows how changes made to your integration would appear in the Zap editor.
If you have an integration in the Platform CLI that you would like to edit in the Platform UI instead, you can create a new version in the Platform UI.
When moving an app from CLI to the Platform UI, we cannot migrate users from previous versions or apps. Existing users will be able to continue using the version they're on, but must upgrade to the new version manually. Existing users would see this [prompt in the Zap editor](https://help.zapier.com/hc/en-us/articles/18755649454989-Update-to-the-latest-app-version-in-Zaps) to optionally encourage them to make the update.
Zapier does not automatically notify all existing users of a new version's availability, but new users would only see the currently promoted/Public version when searching for the app name. We also recommend announcing the changes/new integration version to your general user base via in-app or email marketing to encourage users to switch over.
To export your existing Platform CLI integration to Platform UI:
## 1. Contact Developer Support to create an empty version of your integration
Hiding an app and replacing it with a new app ID built in the preferred tool is [not supported](/platform/publish/integration-publishing-requirements#23-replacement-integration). To export your Platform CLI integration to the Platform UI, contact the [Developer Support](https://developer.zapier.com/contact) team to create an empty version associated with the same app ID.
## 2. Rebuild the integration from scratch
Rebuild the integration from scratch on this newly created empty version in the Platform UI and ensure that this new version has feature parity to the previous CLI version. This new version can then be maintained in the Platform UI by your team. For [Public apps](/platform/quickstart/private-vs-public-integrations), this avoids a repeat of the app review process; as well as retaining previous versions, associated bug reports and feature requests.
> Allow users to remain on the (now legacy) CLI version until they switch over manually, as long as the endpoints are functional. If [Deprecation](/platform/manage/deprecate) is necessary, please note this is significantly more disruptive to our mutual users and should be considered carefully.
When the conversion has been completed, you will be able to see this version and the previous CLI versions in the Platform UI's **Manage > Versions** section.
While you can see the previous CLI versions in the Platform UI, you would not be able edit those versions there. The previous CLI versions would show a lock icon on the various attributes under the *Build* section as they can only be edited from the CLI environment.
You can however, manage the integration, set up and manage embeds (for public integrations) and view the partner dashboard for the integration from the Platform UI.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Change input form field key
Source: https://docs.zapier.com/platform/manage/input-key
## Change scenario
You want to change the key of one or more form field inputs within a trigger, action, or search.
## Impact to users
Modifying the key of a form field input is a breaking change.
Unless precautions are taken, changing the key of an existing form field input will break the field's mapping within the step using it. The previously-mapped value will be dropped, resulting in missed data and/or errors.
## Best practices
* Avoid changing form field input keys
If your API endpoint needs a different property in the request, consider changing the property key instead of modifying the form field input's key.
Form field input keys do not necessarily need to match the properties expected by your API.
Let's say you have a form field input with the key `first_name` (right) and are sending the field's value to your API using a property with the same name, `first_name` (left):
```bash
body: {
first_name: bundle.inputData.first_name; // original
}
```
Then, your API changes and expects the request property to be `firstname` (one word) instead. As shown below, you can change the request property key (left) as needed (`firstname`) while still referring to the form field input (right) based on its original key (`first_name`):
```bash
body: {
firstname: bundle.inputData.first_name; // new - request key and field key can differ
}
```
* Handle both the old and new keys
If it's not possible to simply change a hardcoded request property's key:
We recommend that you design the trigger or action to handle both the old and new key
Using the same example above, let's say that instead of hardcoding your request properties, you were spreading `bundle.inputData` into the body of the API request, so there was a one-to-one relationship between field keys and request properties.
```bash
body: {
...bundle.inputData // original - request keys tied to field keys
}
```
Instead of changing form field input keys, you can use Code Mode (Platform UI) or code (Platform CLI) to modify the request.
For example, below, we create a new object, payload, with all the fields from `bundle.inputData` AND the updated property, `firstname`. Then we delete the old property, `first_name`, and send the updated object in the request:
```js
// copy bundle, add updated property
const payload = { ...bundle.inputData, firstname: bundle.inputData.first_name };
// delete old property
delete payload.first_name;
body = {
...payload, // send updated payload
};
```
With this approach, or one like it, you can change the request as needed without modifying field keys and breaking users' mappings.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Integration insights definitions
Source: https://docs.zapier.com/platform/manage/integration-insights
Integration quality on Zapier boils down to two main pillars: **Health** and **Depth**.
**Health** - does the integration allow users to set up Zaps and keep them running reliably? **Depth** - does the integration have all the functionality to allow users to automate what they want through their Zaps?
Definitions for each of the metrics provided in the integration dashboard below:
| **Metric** | Definition | Filter by |
| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- |
| **New users** | Total number of new users using the integration over a selected period of time. A new user = first time a user creates and activates a Zap with this integration. | Last 7 days Last 30 days Last 90 days |
| **Bugs & feature requests** | Total number of open bugs and feature requests for the integration. | |
| **Daily active users** | Number of users who had a Zap activated in a day. Activated = Zap is on and successfully ran at least one task. | Last 7 days Last 30 days Last 90 days |
| **Monthly active users** | Total number of users who had a Zap activated in a given month. Activated = Zap is on and successfully ran at least one task. | By year |
| **Active Zaps** | Total number of active Zaps over a selected period of time. Active Zaps = number of Zaps currently on and using the integration. | Last 7 days Last 30 days Last 90 days |
| **Daily active Zaps** | Number of active Zaps in a day. Active Zaps = number of Zaps currently on and using the integration. | Last 7 days Last 30 days Last 90 days |
| **Active users retention** | The percentage of active users retained each month. Retention = users who have at least one successful task executed in a given month. | |
| **Zap activation rate by trigger** | For a given trigger, the percentage of Zaps using the trigger and the rate of the ones that activated within 24 hours of creation. The higher the rate, the better the trigger is performing. Activated = Zap is on and successfully ran at least one task. | Last 7 days Last 30 days Last 90 days |
| **Zap activation rate by action** | For a given action, the percentage of Zaps using the action and the rate of the ones that activated within 24 hours of creation. The higher the rate, the better the action is performing. Activated = Zap is on and successfully ran at least one task. | Last 7 days Last 30 days Last 90 days |
| **Usage by trigger** | Number of current live Zaps (Zaps turned on), paused Zaps (Zaps turned off), and total Zaps for each trigger. | By integration version |
| **Usage by action** | Number of current live Zaps (Zaps turned on), paused Zaps (Zaps turned off), and total Zaps for each action. | By integration version |
Public app integrations also have [visibility into embed insights](https://platform.zapier.com/embed/embed-insights).
## Best practices
* Launching a co-marketing campaign or running ads? Track daily and monthly MAU over the launch period to track changes in usage.
* Noticing certain triggers and actions with higher activations? Create additional Zap Templates to expand usage further since you know they are popular functionality.
* Noticing certain triggers and actions with lower activation? Hop into the Zap Editor and test them out yourself. Are there any technical or usability issues you experience? How do other top apps in your category implement similar functionality?
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Migrate users to a new version
Source: https://docs.zapier.com/platform/manage/migrate
If this isn't the first time you've promoted your app - you might have users on older versions.
If you have made minor, non-breaking changes to improve your integration, you can migrate users to the latest version. When you migrate users to your latest version, it will update all of their Zaps, including Zaps turned on.
## What's the difference between minor and major changes?
Minor changes allow Zaps to continue to work as normal. Minor changes need to be compatible with both the previous and new version.
When migrating users to a new version, only active Zaps (not [draft](https://help.zapier.com/hc/en-us/articles/8496260938125-Create-drafts-of-your-Zaps)) are migrated. In some cases, after migration, users that have drafts with an older version of the app may edit that draft and publish the draft, thereby publishing a Zap with an older version of the app.
Zapier recommends migrating a small portion of your existing users to the new integration version to make sure everything is working as expected. Monitor the logs in the Monitoring tab, and migrate the remainder of your users to the new version when ready.
Major changes would cause active Zaps to error and potentially turn off. They would require users to manually update the Zap in order to get it working again. Learn more about [breaking changes to your integration](/platform/manage/planning-changes), best practices and the user impacts.
Zapier recommends not to attempt to migrate users for major changes. **Migration is not required unless the older version will no longer function.** If necessary, you can [deprecate the version](/platform/manage/versions#deprecating-versions) to prompt users to [manually update to the latest integration version](https://help.zapier.com/hc/en-us/articles/18755649454989-Update-to-the-latest-app-version-in-Zaps). Please note that deprecating a version is significantly more disruptive to our mutual users than migrating to the latest promoted version, or than leaving users on an older (now) private version when migration is not possible.
When users are left on an older private version, they will see a [prompt in the Zap editor](https://help.zapier.com/hc/en-us/articles/18755649454989-Update-to-the-latest-app-version-in-Zaps) to encourage them to make the update themselves.
## Migrate users to new version with Platform UI
In the [Platform UI](https://zapier.com/app/developer):
1. In the *Manage* section in the left sidebar, click your **Versions**.
2. On your existing version, click the **three dots icon**
3. Click **Migrate**
4. The *Versioning* sidebar will appear on the right hand side. You'll need to specify:
* **From Version**. Select which version
* **To Version**. Select the new version you wish to migrate new users too.
5. In the *Which users(s) to migrate* field, select either:
* **Percentage**. This will allow you to migrate users, based on percentage between 5% to 100%. This cautious approach helps ensure that minor updates haven't inadvertently caused any issues.
* Select a **percentage**
* Click **Migrate**.
* **Email**. To migrate users one at a time, by email. **Note**: migrating a single user will only migrate Zaps that are private for that user. Zaps that are [shared across the team](https://help.zapier.com/hc/en-us/articles/8496277647629), [shared app connections](https://help.zapier.com/hc/en-us/articles/8496326497037-Share-app-connections-with-your-team), or in a [team/enterprise account](https://help.zapier.com/hc/en-us/articles/22330977078157-Collaborate-with-members-of-your-Team-or-Enterprise-account) will **not** be migrated with this method.
* In the *Email* field, add the **user's email address** attached to their Zapier account.
* Click **Migrate**.
6. To migrate a user's Zaps, Private & Shared, within all accounts for which the specified user is a member (including Team and Enterprise accounts) you can use the `migrate` command with the `--account` flag if [working in the CLI](https://github.com/zapier/zapier-platform/blob/main/packages/cli/docs/cli.md#migrate). Be cautious as this can break shared Zaps for other users.
7. The *Versioning sidebar* will update to show *Update status:Estimating*. Once the migration has been completed, the *Versioning sidebar* will disappear.
Once you're confident that the new version works well, you can go ahead and migrate the rest of your users.
## Migrate users to new version with Platform CLI
For Platform CLI users, it's possible to perform full or partial migrations using the [zapier migrate command](https://github.com/zapier/zapier-platform/blob/main/packages/cli/docs/cli.md#migrate).
**Examples**
```bash
# migrate 100% of your users between version 1.0.0 over to 1.0.1
zapier migrate 1.0.0 1.0.1
# migrate 15% of your users between version 1.0.1 over to 2.0.0
zapier migrate 1.0.1 2.0.0 15
# migrate the specific user user@example.com between version 2.0.0 to 2.0.1
zapier migrate 2.0.0 2.0.1 --user=user@example.com
```
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Change output data response
Source: https://docs.zapier.com/platform/manage/output
## Change scenario
Certain changes made to a trigger, action, or search's output data structure can be breaking changes for users. Even if the output field key(s) remain the same, significant changes to the data structure or format returned from one or more of these fields can affect users' Zaps.
Examples of potential breaking change scenarios:
* An output field representing datetime is updated to return data in ISO-8601 format instead of full date format (Thursday, April 10, 2023 6:30:00 AM)
* A `results` field in a search now returns a list of all search results instead of the single, last created result
* A previously comma-separated list value is updated to return line-items
## Impact to users
Updated output fields from your integration steps can impact the way subsequent actions run in a user's Zap when they are mapped to input fields in those actions.
For example, if a user has set up a Formatter step to parse out the day of the week from the `added_date` field before adding it to a CRM, changing the date format to ISO-8601 will cause the Formatter to process unexpected values, which may lead to issues in the user's Zap.
Another example is a user's Zap configured with a search that always returns a single result based on the latest created date in the `results` field. If the search is updated to return all results, subsequent actions in the Zap may not be set up to handle multiple results, leading to potential problems.
## Best practices
* Use custom code to add your newly formatted data to the existing output data. By doing this, you ensure that users who have already set up their Zaps with the previous data structure will not experience issues due to the changes.
* *For example:* Add a `created_date_ISO` field with the ISO-8601 formatted created date to the output data, instead of updating the current `created_date` value to be in ISO-8601 format. Define clear [output field labels](/platform/build/sample-data) to help users differentiate the fields; updates to field labels are non-breaking.
* Add an optional, boolean input field that users can toggle to choose between returning old and the new data structure. This way, users can decide which data structure best suits their needs for existing and new Zaps. Make sure to set a default value for the input field to automatically return data as your previous version did.
* If you're looking to update a search to return multiple or all search results, instead of the default one result, create a new, separate search for the purpose. This way, users can choose which one to use without encountering issues in their existing Zaps. Differentiate the searches by pluralizing the search: “Find Lead” vs “Find Lead(s)”.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Change output field key
Source: https://docs.zapier.com/platform/manage/output-key
## Change scenario
You may want to update or remove existing output field keys in your Zapier integration. This can happen when you need to clean up output data, remove unnecessary fields, or due to changes in your API's response data.
## Impact to users
If a user has mapped one of the affected fields to an input field in a subsequent step of their Zap, the change can affect that step and potentially the entire Zap's functionality. Imagine if you updated the output field key or removed an output field altogether that a user had mapped to a required field in the next step of their Zap - the step would now error every time.
## Best practices
To minimize disruptions to your users, follow these best practices when updating or removing existing output field keys:
* Remove extraneous fields carefully: If you're cleaning up output data and removing non-essential fields (such as HTTP request data like ‘request type' or ‘request URL'), you should be able to safely remove them. Be cautious and avoid removing fields that users might have mapped to required fields in subsequent Zap actions.
* Maintain backward compatibility: If you're using the Zapier Platform CLI, you can use custom code to ensure backward compatibility with updated response data from your API. Modify the perform methods in your code appropriately to handle these changes.
* Update the static sample: When you have made any changes to output fields, make sure to update the [static sample data](/platform/build/sample-data) accordingly. This ensures that the sample data used for testing and Zap setup by users remains accurate.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Planning and implementing integration changes
Source: https://docs.zapier.com/platform/manage/planning-changes
Before making updates to your integration, it's important to consider the potential impact on user migration and existing Zaps. Ensuring your API and Zapier integration remains backwards compatible is crucial to avoid disruption to users. However, we acknowledge certain changes are sometimes necessary and unavoidable. In such cases, consider the best practice for implementation.
## Effects of Different Changes (Versioning Matrix)
The matrix below illustrates the impact of different changes on your users. For public integrations, this will affect promotion and whether migration is possible. Refer to our best practices to facilitate the upgrade process for yourself and your users.
Columns:
* Add: Adding a net new component
* Update: Making a change to an existing component
* Replace: Deleting/deprecating an existing component and adding a new one in its place
* Delete/Deprecate: Removing an existing component completely
Matrix Key:
* Breaking Change: A modification to the integration which renders existing Zaps incompatible with the new version
* Depends: A modification which may render existing Zaps incompatible with the new version, depending on the implementation
* : A modification to the integration which renders existing Zaps compatible with the new version
* \-: Not applicable
Common changes that can affect the ability to migrate users are detailed in the documentation linked in the matrix. Look for your change and pay attention to the recommended best practices.
Several change scenarios are validated by the platform when you try to *Migrate* after a version promotion, but always be aware of the effects of any changes you make before you even begin implementing those changes.
Change scenarios marked as *Depends* with no linked best practice can vary widely across integrations, so a generalized best practice is not provided; reach out to [support](https://developer.zapier.com/contact) if you need help with your specific change scenario.
| Integration Change | Add | Update | Replace | Delete/Deprecate | Validated by platform? |
| --------------------------------------------------------- | ------------------------------------------------- | -------------------------------------------------- | ----------------------------------------------- | ---------------------------------------------- | ---------------------- |
| **AUTHENTICATION CHANGES** | | | | | |
| **Authentication schemes** | [BREAKING CHANGE](/platform/manage/auth-scheme) | - | [BREAKING CHANGE](/platform/manage/auth-scheme) | - | |
| **Authentication fields - required** | [BREAKING CHANGE](/platform/manage/auth-required) | [Depends](/platform/manage/auth-required) | - | | - |
| **Authentication fields - optional** | | | - | | - |
| **Authentication field key(s)** | - | [BREAKING CHANGE](/platform/manage/auth-keys) | - | - | - |
| **Authentication - token request** | - | | - | - | - |
| **Authentication - test function** | - | | | - | - |
| **TRIGGER/ACTION CHANGES** | | | | | |
| **Trigger/Action - meta info (e.g.: label, description)** | - | | | - | - |
| **Trigger/Action - key** | - | [BREAKING CHANGE](/platform/manage/change-keys) | [BREAKING CHANGE](/platform/manage/change-keys) | - | |
| **Trigger/Action - input field(s) - required** | [Depends](/platform/manage/required-input) | [Depends](/platform/manage/required-input) | [Depends](/platform/manage/required-input) | | - |
| **Trigger/Action - input field(s) - optional** | | | | | - |
| **Trigger/Action - input field(s) - key** | - | [BREAKING CHANGE](/platform/manage/input-key) | [BREAKING CHANGE](/platform/manage/input-key) | - | - |
| **Trigger/Action - input field(s) - field type** | - | Depends | Depends | - | - |
| **Trigger/Action - output data - key(s)** | | [BREAKING CHANGE](/platform/manage/output-key) | [BREAKING CHANGE](/platform/manage/output-key) | [BREAKING CHANGE](/platform/manage/output-key) | - |
| **Trigger/Action - output data - response structure** | - | [BREAKING CHANGE](/platform/manage/output) | [BREAKING CHANGE](/platform/manage/output) | - | - |
| **Trigger/Action - perform function** | - | Depends | Depends | - | - |
| **Trigger type - polling to hook type** | - | [BREAKING CHANGE](/platform/manage/change-trigger) | - | - | |
| **Trigger (polling) - perform function** | - | [Depends](/platform/manage/change-perform) | [Depends](/platform/manage/change-perform) | - | - |
| **Trigger (hook) - perform list** | - | Depends | Depends | - | - |
| **Trigger (hook) - performSubscribe** | - | | | - | - |
| **Trigger (hook) - performUnsubscribe** | - | | | - | - |
| **OTHER CHANGES** | | | | | |
| **Middleware** | Depends | Depends | Depends | Depends | - |
| **Partner's API (overall)** | - | Depends | Depends | Depends | - |
| **Product feature** | | - | - | - | - |
| **Rebrand - (e.g. logo, app name)** | - | | - | - | - |
| **Export UI to CLI** | - | [Depends](/platform/manage/export-cli) | | - | - |
| **Export CLI to UI** | - | [Depends](/platform/manage/export-ui) | - | - | - |
| **Edit Legacy Web Builder integration** | - | [Depends](/platform/manage/versions-legacy) | [Depends](/platform/manage/versions-legacy) | - | - |
If your change is not listed, make sure to still consider whether it changes keys, requires users to provide *new* info, or revokes functionality.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Promote a version
Source: https://docs.zapier.com/platform/manage/promote
After your integration has entered the beta or public status, you can set a new default version for public use. This process is called promoting a version.
Prior to promoting a version, run the [automated validation checks](/platform/publish/integration-checks-reference). All Errors and Publishing Tasks must be validated. Warnings are non-blocking and not strictly required to proceed as they would not prevent you from promoting a version, though we do recommend you review them for usability of your integration.
## Promote a version with Platform UI
1. Log into the [Platform UI](https://zapier.com/app/developer).
2. Select your **integration**.
3. In the *Manage* section in the left sidebar, click your **Versions**.
4. On the version you want to promote, click the **three dots icon**
and **Promote**.
5\. Fill in the [changelog form](/platform/manage/user-feedback#3-close-resolved-issues) and click **Promote**. Selecting specific features added and bugs fixed will automatically queue up the issue(s) to be reviewed by our internal team for closure.
> **Note**: If you have a private integration, you will not see the *Promote* option. Instead, you can [share your new version](/platform/manage/sharing) with users.
## Promote a version with Platform CLI
In the Platform CLI, you can run `zapier promote [version]` to make the specified version number the new public and default version. Learn more about [promoting a version using the Platform CLI](https://docs.zapier.com/platform/reference/cli-docs#promoting-an-integration-version) .
## What happens after you promote a version?
After successfully promoting a version:
* **Zap templates update**: If there are no breaking changes, all Zap templates will be updated to use the new public version.
* **New triggers and actions**: Any newly added triggers or actions will be displayed on your integration's public app page.
* **User experience**: Users who select your integration for a new Zap will interact with the promoted version by default.
By following these steps, you can seamlessly promote a new version of your integration, ensuring that new users have access to the latest features and improvements.
## Video Tutorial
You can refer to this video on promoting a version:
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Add new required input field
Source: https://docs.zapier.com/platform/manage/required-input
## Change scenario
Your app's API endpoint adds an additional field for filtering records (trigger/search) or an additional property for created records (action).
## Impact to users
Adding a new **required** input field or making a *previously* optional input field now required, would break existing Zaps without a value for the field. There is no automated check for this when migrating so though it may seem possible, it will be a breaking change for migrated users.
## Best practices
Consider the following options:
* Add new input fields as optional. Use a combination of custom error handling to throw an error if the field is empty and help text to explain the field is required.
* Use [Code Mode](/platform/build/code-mode) (Platform UI) or code in `Perform` (Platform CLI) to set a default value for the inputField if users have it blank in their existing Zaps. This would only be successful if a universal default could apply to all users (would not work for custom fields for example).
* Create a new trigger/action/search (T/A/S) with the required inputField; and hide the previous T/A/S. That way, existing Zaps will continue to work with the previous (and now hidden) trigger/action/search definition, and new Zaps will be forced to provide a value for the required field.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Share your integration
Source: https://docs.zapier.com/platform/manage/sharing
Once an integration is public, all users would have access to it when searching for an app's name in the Zap Editor, or in the [Zapier App Directory](https://zapier.com/apps).
For private integrations, there are two ways to share access with users:
## 1. Invite users with a public link
You can share a link with users to all versions of your integration.
* You can't view a list of users that have accessed the public link.
* You can't revoke a link invite, once shared. If you require control over who accesses your integration, we recommend inviting users by email.
* [Log into the Platform UI](https://zapier.com/app/developer)
* Select **My Integration**.
* In the *Integrations* section, select your **integration**.
* In the left sidebar, under *Manage* click **Sharing**.
* Click to copy the invite public link.
* You can access the public link in this way for integrations built in the Platform UI or the Platform CLI.
* Generating a public sharing link for one specific version only is available in the [Platform CLI](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#sharing-an-app-version), but not the Platform UI.
Share the invite link with users via your website or other method. The link will take users to your integration landing page where they can follow the on-screen instructions to accept your invite to all versions of the integration.
## 2. Invite users by email
Inviting users by email gives you the option to select which version of your integration they can access. All users invited by email are tracked in the Sharing tab, allowing you to view and control who has access to your integration.
* You can only invite 200 users by email.
* [Log into the Platform UI](https://zapier.com/app/developer) or refer to the [Platform CLI documentation](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#sharing-an-app-version).
* Select **My Integration**.
* In the *Integrations* section, select your **integration**.
* In the left sidebar, under *Manage* click **Sharing**.
* In the *Email* field, insert the **user's email**.
* (Optional) In the *Versions* dropdown menu, select which **version** of your integration you want your user to access.
* Click **Invite**. This will instantly send the user an email from [notifications@mail.zapier.com](mailto:notifications@mail.zapier.com).
* You can send invitations in this way for integrations built in the Platform UI or the Platform CLI.
The user's email will be added to the table in your Sharing settings. From there, you can track the status of their invite. They will need to accept the email invite in order to be able to access the integration.
## Revoke invites sent by email
Revoking invites will remove a user's access from that integration version, and all Zaps will immediately be paused. The user won't be able to use your app again until they're re-invited or it has gone public. In practice, this is not used often as it's very disruptive to users.
### Revoke public link invite
It's not possible to revoke a user's access to or change a public link invite once it has been shared.
### Revoke email invite
There are two ways to revoke email invites using either the Platform UI or Platform CLI.
#### Zapier Platform UI
1. [Log into the Platform UI](https://zapier.com/app/developer)
2. Select **My Integration**.
3. In the *Integrations* section, select your **integration**.
4. In the left sidebar, under *Manage* click **Sharing**.
5. In the row for your user, click **Delete**.
6. Click **Really?** to revoke the access for that user.
#### Zapier Platform CLI
> **Note**: This method will remove users from all versions of your integration.
1. In your terminal, navigate to the directory of your integration (the directory with the `.zapierapprc` file).
2. Run zapier `users:remove user@example.com`. Replace `user@example.com` with the email address that you'd like to revoke access for.
3. The CLI will prompt you to confirm your revocation, type `Y` and click `Enter`.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Respond to user feedback and bugs
Source: https://docs.zapier.com/platform/manage/user-feedback
For public integrations, Zapier's Support team logs user requests and reported problems in Zapier's issue tracker, that your team can see from the _Bug & Feature Requests_ page in the Manage section.
Problems with your public integration, authentication and API calls will be logged as `bug`, while new functionality users request for your app integration will be logged as `feature request`. You have the ability to filter open `bugs` and `feature requests` to view issues by individual Trigger or Action.
## 1. Monitor issues reported
* Whenever a new issue is added or updated, Zapier will log it in the *Bugs & Feature Requests* page of your app's Developer Platform page.
* Issue notifications are automatically sent to all confirmed Administrators and Collaborators on the integration team. If an Administrator or Collaborator is listed as `Invitation Pending`, they will need to accept the invite before they start to receive issue notifications.
* Bug count is not as important as how many of your users are affected overall and what percentage of the app's overall monthly active users that impacts. Past history on closing bugs doesn't influence your app's current health score.
* Affected user counts on issues typically underrepresent the actual totals, as only a small portion of all users facing an issue take the time to contact Zapier Support.
### Utilizing issue statuses
Maintaining accurate issue statuses during regular triage and review of your integration's issues is critical for keeping your integration healthy. Not only do statuses help your team track progress and build roadmaps, but they also signal your engagement and prompt reviews for fixed issues to the Zapier team.
Available statuses:
* *Open*: The issue is open and no action has been taken.
* *Planned*: Work has been committed to address the issue, but has not started.
* *In Progress*: This issue is being actively worked on.
* *Done*: Work is completed, and the updates for the issue have been promoted.
* *Under review*: Zapier is reviewing the work completed on the issue.
* *Rejected*: After review, Zapier deemed the issue resolution not complete.
Once an issue is resolved, update the issue status to `Done`. You will be prompted to select one of the following issue resolutions:
* *Resolved*: Work is completed and updates have been promoted.
* *Won't Do*: This issue won't be actioned (i.e. not on the roadmap, not technically possible, etc.). A comment explaining why is required.
* *Duplicate*: The issue is a duplicate of another issue. Please note the duplicate issue in the required comment.
* *Cannot Reproduce*: All attempts at reproducing this issue failed.
All issues marked `Done` are reviewed by the Zapier team for accuracy and completion. Any necessary explanation or feedback will be provided via comments on respective issues after the internal review. Please respond with questions or concerns on the appropriate issue to keep discussions clear.
Plus, any of the statuses above can sync right into your preferred issue-tracking tool thanks to the [Zapier Issue Manager integration](/platform/manage/user-feedback#4-consider-zapier-issue-manager-zim).
## 2. Respond to issues in a timely manner
* Reply to the Zapier team about the issue within the *Bugs & Feature Requests* page to keep communications consistent for both your team and ours. These issues and comments are not visible to affected users; and users will only be notified when an issue is verified as closed/resolved by Zapier Support.
* Lowering your count of issues will help improve your integration's [health score](/platform/publish/partner-program#integration-health-score) and increase your tier in the [Partner Program](https://zapier.com/platform/partner-program). The more you maintain a bug-free, quality integration, the more essential your product becomes to your users' workflows. This sets you up to reduce churn, drive account upgrades, and increase customer lifetime value.
* Regardless of the size of your integration's user base, keeping the percent of monthly active users affected by open bugs under double figures (and ideally at 0) is recommended for a healthy integration.
* Allocate ongoing resources in your team's product roadmap for the maintenance of your Zapier integration to avoid surprise work or gaps in functionality. Consider a [Zapier Solution Partner](https://zapier.com/partnerdirectory/projects/create) to help you fix one-off bugs or maintain your integration.
* Keep issue statuses up-to-date as you regularly review, triage, and address your integration's issues. See the [`Utilizing issue statuses` section](/platform/manage/user-feedback#utilizing-issue-statuses) below for more details and best practices.
### Dormant Issues
Any reported issue with no updates from you, Zapier Support, or end users for a year will now be automatically closed. This keeps your workspace current and focused, making it simpler to stay on top of active issues.
## 3. Close resolved issues
* Bugs and feature requests require review and verification from Zapier's Support team before they can be closed. When an issue is closed, email notifications are sent out to all affected users on the issue, notifying them of the update.
* Whenever a new version of your integration is promoted via the UI, you'll be prompted with a changelog form asking you to identify which feature requests or bugs were resolved and to provide a user-facing description of the changes. Issues identified in the changelog will automatically be queued for review by our Support team and closed once resolution is confirmed. Promoting via the CLI doesn't currently support changelogs.
* You can also request issues to be closed manually by updating their statuses to `Done`. Make sure updates are promoted to the latest version of your integration, and users are migrated if possible before marking issues before marking issues as `Done`, as it will be reviewed by a Zapier support member. See the [`Utilizing issue statuses` section](/platform/manage/user-feedback#utilizing-issue-statuses) below for more details and best practices.
## 4. Consider Zapier Issue Manager (ZIM)
* If you prefer syncing and managing issues from your own issue-tracking tools (such as Jira or Trello), create Zaps using Zapier Issue Manager.
* Zapier Issue Manager is available to all *Beta* and *Public* Zapier partners who own and maintain their own integration. To request access, submit the request form below.
[Click here to request access to Zapier Issue Manager](https://zim.zapier.app/request)
Zapier Issue Manager offers the following for building Zaps:
### Triggers
* New Issue
* Issue Closed
* New Comment
* Affected User Added
* Issue Reopened
### Actions
* Create Comment
* List Issues
* Find Issue
* Close Issue
* Update Work Status
* Generate Report
Here are some Zap templates to help you get started using Zapier Issue Manager.
## 5. Monitor integration insights
* [See all the metrics tracked](/platform/manage/integration-insights) in this table, or access them for any integration you are an Admin or Collaborator on from the *Dashboard* tab of the Platform UI. Insights include important data on both the integration's growth and usage, such as monthly active users, retention rates, and Zap usage by triggers and actions.
* Filter growth metrics by the last X number of days to identify trends and changes in user activity in correlation to marketing initiatives, integration changes, and product updates like [embedding Zapier](https://platform.zapier.com/embed/full-zapier-experience).
* Usage details for each trigger and action will show which functionalities are the most popular and being effectively utilized.
* Share access to the insights by [inviting collaborators](/platform/manage/add-team) to the integration without giving them permissions to make changes to it.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Version lifecycle states
Source: https://docs.zapier.com/platform/manage/version-lifecycle-states
Learn about the different lifecycle states an integration version can go through, including private, promoted, available, legacy, deprecating, and deprecated versions.
When you create a new integration version in Zapier, it goes through different lifecycle states. Understanding these states is crucial for managing your integration effectively. They are as follows:
* Private
* Promoted
* Available
* Legacy
* Deprecating
* Deprecated
## Private
When you first create a new integration version, it automatically starts in a **private** state. This is the default state for all new versions.
In the private state:
* Only you and your team members can access and test the version
* You can make changes and updates to the integration
* You can [share the version](/platform/manage/sharing) with specific users for testing
* The version remains private until you take further action
## Promoted
If your integration is public or intended to go public, you can promote a version to make it available to all Zapier users. When a version is promoted:
* It becomes the default version for all new automations
* It is visible in the Zapier app directory (for public integrations)
* Existing Zap templates may be automatically updated to use this version
* You must always have one promoted version for public integrations
Important notes for promotion:
* Only one version can be promoted at a time
* When you promote a new version, the previously promoted version will be automatically demoted to private
* You cannot promote a version that has been demoted, legacy, or deprecated
* All [validation checks](/platform/publish/integration-checks-reference) must pass before promotion
## Available
If a version is promoted, the previous promoted version automatically becomes "Available".
Available versions continue to work for automations that use them.
## Legacy
A version can be marked as legacy when you no longer recommend it for new automations, but it is expected to continue working for any current automations. To set a version as legacy:
* The version must be in a private or demoted state
* You cannot mark a currently promoted version as legacy
* Legacy versions can still be used by existing automations but are not available for new automations
Important considerations for legacy versions:
* You cannot migrate automations to a legacy version
## Deprecating
When you mark a version as deprecated with a deprecation date, it will automatically be set to "Deprecating" until the deprecation date.
While a version is in the deprecating state, it will continue to work for existing automations, but it will not be available for new automations.
See [Deprecated](#deprecated) below for deprecation details.
## Deprecated
Deprecation is the final state in a version's lifecycle. When you deprecate a version:
* Users will be notified that they should migrate to a newer version
* The version will continue to work for a specified time period
* After the deprecation date, the version will no longer function
* You must deprecate a private, demoted or legacy version, not a currently promoted version
Important notes about deprecation:
* Set a future deprecation date to give users time to migrate
* Ensure you have a newer version available for users to migrate to
* Consider the impact on existing users before deprecating a version
See [Deprecate or delete a version](/platform/manage/deprecate) for more information.
## State Transitions
Here's how versions typically move through states:
1. **Private** - Every new version starts here, allowing you to build and test without affecting users.
2. **Promoted** - When your version is ready for public use, you promote it, making it the default for all new automations. The previously promoted version automatically becomes **Available**.
3. **Legacy** - When you release a newer version with significant improvements, you may mark older versions as legacy. These versions still function for existing automations but aren't recommended or available for new ones.
4. **Deprecating/Deprecated** - When a version will no longer be supported (e.g., due to API changes from the service provider), you deprecate it with a future end date. This gives users time to migrate their automations before the version stops working.
Remember that you must always have a promoted version if your integration is public, and you should carefully plan version transitions to minimize disruption to your users' automations.
For more information on managing versions, see:
* [Promote a version](/platform/manage/promote)
* [Migrate users to a new version](/platform/manage/migrate)
* [Deprecate or delete a version](/platform/manage/deprecate)
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Versions
Source: https://docs.zapier.com/platform/manage/versions
Versions in Developer Platform allow developers to create multiple iterations of their integration to experiment with and implement new features without affecting existing users. Each integration can have many versions, but only one version can have a public status at a one time.
Versions allow you to have:
* **Seamless user experience**: Existing users have uninterrupted service, while new features are being tested and deployed.
* **Incremental upgrades**: Developers can facilitate phased roll outs of new features, allowing for thorough testing and feedback collection before full deployment.
* **Version management**: Developers have a structured approach to migrate users to updated versions and deprecate older versions when applicable.
## Managing versions in Platform UI
To manage your versions:
1. Log into the [Platform UI](https://zapier.com/app/developer).
2. Select your **integration**.
3. In the *Manage* section in the left sidebar, click your **Versions**.
This page shows a list of all versions of the integration, along with status, number of active users and active Zaps on each. For public integrations will also show the changelogs input when a new version is promoted.

Learn more on:
* [Clone a version](/platform/manage/clone)
* [Promote a version](/platform/manage/promote)
* [Migrate users to a new version](/platform/manage/migrate)
* [Deprecate or delete an version](/platform/manage/deprecate)
## Managing versions in Platform CLI
Integrations created with the Platform CLI cannot be edited in the Platform UI, however you can view the available versions in the Platform UI. You can also run the [`zapier versions`](https://github.com/zapier/zapier-platform/blob/master/packages/cli/docs/cli.md#versions) command to see the same information in your local terminal.
### What do I do if I am blocked from promoting or migrating integration versions?
Zapier may fix bugs or add new features to your integration and release these as part of a new integration version.
In the event that Zapier has made changes to an integration version you own, you will be unable to do the following until you update your local files by running `zapier pull`:
* push changes to the promoted version
* promote a new version
* migrate from one version to another version
Run `zapier pull` to update your local files with the latest version and remove these restrictions. Any destructive file changes will prompt you with a confirmation dialog before continuing.
## Who can view your versions?
For public integrations, which are searchable in the Zap editor or in the app directory, a user who selects your integration in the Zap Editor will be using the current public version by default.
For both [private and public integrations](/platform/quickstart/private-vs-public-integrations), only team members added to the integration, or users with whom you have shared private versions with specifically, will see those versions as well.
### **How will my users identify a new version?**
As an integration admin, you will always see all the integration versions when connecting the app, but the end user should see only the published version.
For end users, the public version will be the one showing only the name of the integration, with no version number on it.
For private integrations, you can either invite the users to the new version via the users’ email addresses or use the sharing link to invite the users.
## Editing versions
To make sure that existing Zaps can continue to work consistently, the Developer Platform only allows you to edit versions that have a private status and have fewer than 5 users. Versions that are public or have more than 5 users will show a warning message prompting you to clone the version instead.

When making integration updates in newer versions, consider the potential impact on user migration and existing Zaps. Ensuring your API and app integration on Zapier remains backwards compatible is crucial to [avoid disruption to users](/platform/manage/planning-changes).
### **Is there any way to bulk-update the API endpoints?**
While there's no automatic way to do this in the Platform UI, you might consider migrating your integration to the CLI, which can streamline the process of updating endpoints. You can find more information on how to export your integration to the Platform CLI in this guide: [Export Integration to Platform CLI](/platform/manage/export-cli).
If updating the base URL is your main concern, you could use environment variables to host the base URL. You can reference it using `{{process.env.YOUR_KEY}}`, which might make future bulk updates easier.
***
[*Need help? Tell us about your problem and we'll connect you with the right resource or contact support.*](https://developer.zapier.com/contact)
# Manage a legacy integration
Source: https://docs.zapier.com/platform/manage/versions-legacy
## Legacy API configuration settings
Converted legacy Web Builder integrations have slightly different API Configuration tabs for authentication, triggers, and actions then integrations (and new triggers or actions) built in Platform UI. In new integrations, each API field will let you set the API call settings in a form, or switch to [Code Mode](/platform/build/code-mode) to add custom JavaScript code for that call and its response parsing. In converted integrations, however, you will see static text fields for each API call URL. If you need to customize the API call or response bundle parsing, you will need to do so from the [Legacy Scripting](https://platform.zapier.com/legacy/scripting) settings.
## Where's my code?
To find your find your previous code:
1. Log into the [Platform UI](https://zapier.com/app/developer).
2. Select your **integration**.
3. In the *Build* section in the left sidebar, click your **Advanced**.
4. Click the **Legacy Web Builder** tab.
Your converted integration looks a little different than if you'd started it from scratch in the Platform UI, but should feel pretty familiar (apart from versioning). One thing you may notice are sections where the configuration is a code block, and the code is calling `z.legacyScripting.run()`. To make integrations written in the old environment run without modification, in the new environment Zapier ‘wraps' your custom code and API configuration, and created a runtime library that emulates the behavior of the old platform. So each time you see this, you can recognize it as an artifact of this emulation - we're calling into the emulator to perform the operation we need using your original code and configuration.
Where you added custom scripting code, the `z.legacyScripting` will call these functions to drive your triggers, actions, and authentication transactions.
You can edit this code as before, this time in a redesigned editor that does not take up your full screen. Be sure to click **Save** after editing your integration code, as Zapier does not auto-save changes.
> **Note**: Zapier recommends to understand [versioning model of the Platform UI](/platform/manage/versions) before making any code changes.
*→ Find detailed documentation on how to edit your integration's code in [Legacy Scripting](https://platform.zapier.com/legacy/scripting).*
## What is not included in Platform UI?
Platform UI includes most of the features you would expect from the legacy Web Builder, along with new features to help better manage your integration. In converted integrations, you will see some additional features to manage existing authentication, triggers, and actions. If you add new triggers or actions to your integration, though, these features will not be available in the new items, including:
* **Scripting**: The legacy Web Builder combined all code into one Scripting page that let you add custom code for authentication, triggers, actions, and response data parsing. If you add new triggers or actions to your integration, though, use [Code Mode](/platform/build/code-mode) to customize your API call or response bundle parsing. Learn more in [legacy scripting](https://platform.zapier.com/legacy/scripting).
* **Custom results fields**: The legacy Web Builder included an option in triggers and actions to make an API call that would fetch custom result field names. The Platform UI does not include this option for new triggers and actions, though it does let you continue to use this option in converted, existing triggers and actions. If you add new triggers or actions to your integration and need to fetch custom results fields, you will need to add that to the trigger or action's API call in the code mode.
* **OAuth v1**: Platform UI does not support OAuth v1 for new integrations, and instead requires new integrations to use OAuth v2 authentication. You may continue to maintain existing OAuth v1 authentication in converted integrations, but if you make a new version of your integration or re-build it in Platform UI, you will need to use a newer authentication scheme.
* **Advanced Editor**: The legacy Web Builder included an *Advanced Editor* option to edit your integration in JSON text instead of the web UI editor. That feature is no longer available in Platform UI, for new or converted integrations. If you would prefer to manage your integration in JSON text and code, the better option would be to export your integration to Platform CLI to manage it from your local development environment. Once your app has been converted to the Platform UI, you will have the option of [exporting your app to Platform CLI](/platform/manage/export-cli).
* **Files**: The legacy Web Builder included some support for [file handling](/platform/reference/legacy-scripting#files). The Platform UI does not include capabilities for working with files. To work with files, [export your app to the CLI](/platform/manage/export-cli) after it is converted.
## Creating new triggers and actions
You'll be able to continue your development, creating new triggers and actions, in your converted Web Builder integration. When you create a new trigger or action, the interface will look a little bit different than those triggers and actions that were converted over from the legacy platform. It will look familiar to you. The big difference is when configuring an HTTP API request, you'll have many more options to customize headers and parameters without having to write custom code. And when you do need to use custom code, you'll do so in that trigger/actions's UI, rather than in a common script file. We'll talk about differences in the scripting environment next.
## Differences when writing custom scripting code
The following applies when you're building *new* triggers and actions, and working with custom scripting code. These are the idioms of the way operations are executed on the new platform.
> **Note**: If you're making changes to the code in the **Legacy Web Builder tab**, the following statements do not apply. That code is run in an “emulated” context and works just like the old environment.
### Code is scoped to the individual trigger or action
When you're writing custom scripting code in the new platform the scope of that code is local to that trigger or action. This makes it easier to understand when a request will be handled by custom code, or simply configuring a request for default request handling. It also means you can't easily share code between different triggers and actions. For that, have a look at moving to the Zapier CLI, which is geared toward teams, projects with custom code, projects that need 3rd party libraries, etc.
> **Tip**: A handy way to understand this is to have a look at the [schema](https://github.com/zapier/zapier-platform/blob/main/packages/schema/docs/build/schema.md) of the integration definition you're building. [Here](https://github.com/zapier/zapier-platform/blob/main/packages/schema/docs/build/schema.md#basicpollingoperationschema) you'll see the structure of the definition of a polling trigger. Notice that the `perform` field takes a request configuration object, or it simply takes a Javascript function. The Platform UI reflects this. When you configure an API interaction, you use the Form Mode to configure a request, or you use Code Mode to write a function to be called instead.
### No pre or post functions
In the legacy Web Builder, you could write custom code that ran before the request was made, or after the request returned, or you could take over complete control of making the request and returning data to Zapier. In Platform UI, there is only the ‘complete control' option. Your request can implement a `perform` function that takes a bundle as input and is expected to return data when the request handling is completed.
### Promise based API
A big difference in the API of the new environment is that the request API is asynchronous, using promises rather than synchronous requests or callbacks. For developers new to Javascript promises this can be a small stumbling block. We recommend spending a few minutes getting familiar with how promises work in general. The `z.request` library works very similarly to the promise-based Fetch API, so most articles and tutorials about that apply to working with custom code in Zapier's environment.
### No libraries included
The legacy Web Builder tool included several JavaScript libraries, such as Underscore and jQuery, in its context that you could use in your script code. Those are no longer available when writing scripting code in the Platform UI. You'll be able to use any JavaScript feature of Node.js (version 12 at the time of this writing, possibly v14 by the time you're reading this), including its standard library with `z.require`.
If you need, or prefer to use, a 3rd party Javascript library you'll want to switch to the Platform CLI where you can install modules from npm and reference them throughout your code.
#### Structure and naming of the Bundle Object is different
Field names and structure of the Bundle is slightly different between the Legacy Web Builder and the new platform. Learn more details in our [Bundle docs](/platform/reference/cli-docs#bundle-object).
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Zap activation rates
Source: https://docs.zapier.com/platform/manage/zap-activation
Consider all of the Zaps that users try to create with your integration's triggers, actions, or searches. The Zap activation rate is the percentage of those Zaps that actually activated within 24 hours of creation, meaning the Zap ran at least one successful task.
A low activation doesn't necessarily mean something is broken. Maybe the user started to make a Zap, put the kettle on, forgot about what they were doing and didn't bother ever coming back to finish what they started.
It can also highlight that certain triggers or actions are proving challenging to set up in a Zap or are erroring when run. Perhaps your trigger sample doesn't return the custom fields the user is looking to map in the Zap or the user gets confused by unclear input fields while setting up their action; these are common reasons a user may abandon setting up their Zap.
## Key Zapier insights
Zap activation rates at the individual trigger and action level are a great leading indicator of performance and usability. Simplifying authentication is a vital first step. If users can't authenticate or get their Zaps enabled and activated, they stand little chance of ongoing success.
## Best practices
Give users the best chance to successfully activate their Zaps by making the integration as familiar and easy-to-use as possible:
* Follow our [Integration publishing requirements](/platform/publish/integration-publishing-requirements) which provide detailed user experience best practices for building your public integration.
* Create [Zap Templates](/platform/publish/zap-templates) for popular use cases to simplify the setup process and decrease room for user error.
* Head to the Zap editor to create and test Zaps using your own integration. This gives you firsthand experience on how users interact with the integration.
* Keep your app and Zapier integration parallel to maintain a consistent experience for mutual users.
* Object and field names referenced in the integration should parallel names in your app. For example, don't name your trigger *New Lead* if they are referred to as *Contacts* in your app. This makes it hard for users to find the functionality they want.
* Provide all available input fields in your app in the integration step, including custom fields.
* Match the field types in your app to the integration. For example, if a field is a static dropdown in the app, implement it as the same type within the integration.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Add or modify integration branding and details
Source: https://docs.zapier.com/platform/publish/add-or-modify-branding
When creating a new integration in the Platform UI from the link `https://developer.zapier.com/app/new`, you'll be prompted to add the app name, description, homepage URL and logo.
## Platform UI
It is also required to complete the Intended Audience, your role and the app's category.
## Platform CLI
When creating a new integration in the Platform CLI, you can optionally add the app name, description, and homepage URL to the `package.json` file. The rest of your app's branding needs to be added in the Platform UI once you `zapier push` your integration for the first time.
Build your integration locally first. Once you've added your app's core details, authentication, triggers, and actions, push your integration to Zapier with a `zapier push` command. Zapier will use the name you added in the CLI integration settings, along with a placeholder icon for your app.
Next, add your app's branding via the Platform UI at [developer.zapier.com/](https://developer.zapier.com/). There you will see every Zapier integration you've built. The *My integrations* section includes every app you've added via Zapier's Platform UI or CLI. Look for the integration you built with Zapier CLI and select.
Only the branding for your CLI-built app can be edited in the UI; authentication, triggers, and actions must be edited in your local environment and pushed to Zapier.
To edit branding, select the gear icon in the upper left hand corner near your app's name and placeholder icon. Edit your integration's name and description, and upload your app's logo (a square, transparent PNG at least 256x256px), meeting [requirements](/platform/publish/branding-guidelines). Below that, set your app's Intended Audience, your role and the app's category. Select *Save*.
## Modify or rebrand your integration
### Private integrations
For integrations in `private` status, branding can be updated anytime on the Integration Settings page. Access Integration Settings by clicking the gear icon to the right of the integration name.
### Public/Beta integrations
For integrations in `public` or `beta` status, branding changes need to be processed by our Partner Support team. To request branding changes, visit the Integration Settings page and click the form linked at the top of the page.
The app ID and your Zapier account email will automatically populate into the form. Provide only the details you want updated on your integration's directory page, and submit the form. You'll receive a confirmation email of your submission, and the Partner Support team will process the changes within 1 business day. You'll receive a second email confirming once the changes have been made.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Guide to Zapier Partner Program Benefits
Source: https://docs.zapier.com/platform/publish/benefits-guide
Zapier offers a variety of marketing and support benefits to partners. This cheat sheet is designed to help you understand when and how you can access each of these benefits as you unlock them.
## Accelerate your access to these benefits by embedding
**Unlock the benefits of the Zapier Partner Program faster by embedding your integration into your product via your help docs, integration pages, or blog posts.** There are two ways to do this:
1. If you're in Beta, you'll exit Beta the day after we detect a signup that originates from your embed
2. If you're already a Partner, you can access some of the benefits of the next tier faster if you meet these requirements:
* we detect a signup from an embed that originates on your site
* your integration has a Healthy or Exceptional health score
* your integration meets a minimum active user count (40 for early Silver benefits, 300 for early Gold benefits, 2,500 for early Platinum benefits)
Embedding your integration not only enhances your product's functionality but also fast-tracks your access to higher-tier benefits. It's our way of incentivizing partners to integrate with Zapier and reap the rewards sooner.
## Next steps
* Review your integration tier on the Partner Program page in the developer dashboard
* Plan benefit redemption around your integrations' marketing calendar (and keep track of the annual usage limit of each benefit)
* Highlight your integration in your product and marketing assets with our [partner embedding tools](https://zapier.com/l/partner/solutions)
## Access to our Partner Support team
Access to integration best practices through our dedicated Support team.
* **How to access this benefit:** Submit our [contact form](https://developer.zapier.com/contact)
* **Eligible tiers:** Bronze+
## Complimentary Zapier account for testing integration updates
Access to a complimentary workspace with premium features, giving your integration team access to features to support the ongoing development and maintenance of your integration.
| | |
| ----------------- | -------------------------------------------------------------------------------------------------------------------- |
| **Tier** | Bronze+ |
| **How to redeem** | Submit the form linked at the top of the “Manage Team” page for your eligible integration on the developer platform. |
| **Opportunity** | Use Zapier Partner Sandbox to test integration updates before promoting them to users. |
## App directory listing lead generation button
A “Learn More” button ([example](https://cdn.zappy.app/8a9c2c36af184c011c6377dbd7b8d54c.png)) is added to your app's listing in the App Directory. This way, anyone who lands on this page can directly visit your site for more information on your product.
| | |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Tier** | Silver+ |
| **How to redeem** | Automatically redeemed for you. Customize this button with UTM parameters of your choice reaching out to our team at [partners@zapier.com](mailto:partners@zapier.com) |
| **Opportunity** | Make it easy for potential users to explore your product with just one click through the “Learn More” button for enhanced lead generation. |
## Community post inclusion of your integration updates
We showcase new triggers, actions, and searches added to your integration, as well as user-reported issues closed with a “Resolved” statues in a monthly Community post.
| | |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Tier** | Silver+ |
| **How to redeem** | Automatically redeemed for you. We capture new triggers, actions, and searches added to your integration, as well as user-reported issues closed with a “Resolved” status, and include them in a Community post. |
| **Opportunity** | Actively requests feedback from our mutual users on these updates, fostering direct engagement with users and enhancing the overall user experience. |
| **Best used** | Don't miss a chance to promote these updates with your users, and engage with users by responding to their comments. |
## Featured Integration in the App Directory
Boost your integration's exposure through a feature placement in our app directory ([example](https://cdn.zappy.app/c18cd47ae39d442aa2f6ea8aadc5cc82.png)).
| | |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Tier** | Silver+ |
| **How to redeem** | Select a 1-week period where you anticipate high customer engagement and email [partners@zapier.com](mailto:partners@zapier.com) requesting to redeem. |
| **Opportunity** | Users are more likely to discover your integration when they're viewing your integration's category in our app directory. |
| **Frequency** | Once every 365 days (rolling) |
## Spotlight in the weekly Zapier blog email newsletter
Showcase your integration to 20,000 engaged Zapier users.
| | |
| ----------------- | ----------------------------------------------------------------------------------------------------------------------- |
| **Tier** | Silver+ |
| **How to redeem** | Email us at [partners@zapier.com](mailto:partners@zapier.com) stating your interest in redeeming this perk. |
| **Best used** | Extend the spotlight on LinkedIn by posting a screenshot of your banner, and be sure to tag @Zapier — we'll amplify it! |
| **Frequency** | Once every 365 days (rolling) |
## Blog feature of your integration updates
We highlight new triggers, actions, and searches added to your integration in a monthly blog post (shared with a large Zapier audience).
| | |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| **Tier** | Gold+ |
| **How to redeem** | Automatically redeemed for you. We capture new triggers and actions added to your integration and promote them in the blog post. |
| **Opportunity** | If you add a feature to an existing trigger or action that you think customers will love, send us an email. |
| **Best used** | Don't miss a chance to promote these updates with your users by linking this announcement to a post on your networks. |
## Prioritized marketing inclusion
Get ahead with early access to Zapier-initiated co-marketing campaigns, giving your integration more exposure and engagement opportunities.
| | |
| ----------------- | -------------------------------------------------------------------------------------------------------------------- |
| **Tier** | Platinum |
| **How to redeem** | Automatically included. We'll prioritize invites for Platinum Partners to participate in our co-marketing campaigns. |
| **Opportunity** | Boost your integration's visibility and user engagement by being featured in high-impact marketing efforts. |
| **Best used** | Take advantage of early access to promote your integration effectively across multiple channels. |
## Priority developer support
Request dedicated support for your integration and product roadmap from a Zapier Solutions Engineer. Technical troubleshooting and code review are available.
| | |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| **Tier** | Platinum |
| **How to redeem** | Email [partners@zapier.com](mailto:partners@zapier.com) to redeem this benefit. |
| **Opportunity** | Use this tailored benefit to approach adding new features or fixing new bugs on your integration, based on your product goals. |
## 1:1 integration advocacy session
Get expert 1:1 support from Zapier's Solution Engineering or Marketing teams to optimize your integration and boost visibility.
| | |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Tier** | Platinum |
| **How to redeem** | Email us at [partners@zapier.com](mailto:partners@zapier.com) stating your interest in redeeming this perk. |
| **Best used** | Achieve more with less while keeping Zapier at the center of your automation journey. You'll uncover niche use cases that can help deliver new features and functionalities. |
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Best practices for showcasing your integration
Source: https://docs.zapier.com/platform/publish/best-practices
Sharing well-crafted content about your Zapier integration can help you improve user adoption, highlight key use cases, and simplify integration processes. Need some inspiration? The following examples show how some of our partners are effectively communicating their Zapier integrations across different platforms.
# Best practices for showcasing your integration
Sharing well-crafted content about your Zapier integration can help you improve user adoption, highlight key use cases, and simplify integration processes. Need some inspiration? The following examples show how some of our partners are effectively communicating their Zapier integrations across different platforms.
## Integration pages
A popular option for showcasing your integration is to create a dedicated, visually engaging landing page for Zapier on your website’s integrations directory.
To drive faster adoption, follow these best practices for your page:
* **Link to customer stories** — Share customer success stories that reference how Zapier has saved your users time and effort.
* **Add quotes** — Feature quotes that showcase how Zapier has driven meaningful improvements in users’ workflow efficiencies.
* **Embed Zap templates** — Show the most relevant use cases for your customers, and embed related Zap templates directly onto the page with our [embed tools](https://zapier.com/developer-platform/embed-tools). That way, users can easily build Zaps—without ever having to leave the integration page.
*Examples*: [BrightHR](https://www.brighthr.com/ca/integrations/zapier/), [SwagUp](https://www.swagup.com/integrations/zapier), [TrueReview](https://www.truereview.co/app/zaps), [Pipedrive](https://www.pipedrive.com/en/marketplace/app/zapier/10f6b602cda330ef)
## Help documentation
Write help documentation with clear, step-by-step instructions for integrating Zapier with your app.
These best practices can help your docs stand out:
* **Embed Zap templates** — Just like with your integration pages, embedding Zap templates directly in help docs can help reduce the friction of setup.
* **Be detailed** — Guide users who might be completely new to automation with detailed instructions.
* **Use visuals** — Keeping the docs visually engaging can complement your copy, building your users’ confidence even more.
*Examples*: [Jotform](https://www.jotform.com/help/how-to-use-zapier-with-jotform/), [Kajabi](https://help.kajabi.com/hc/en-us/articles/360037178613-How-to-Use-Zapier-With-Kajabi), [ClickSend SMS](https://help.clicksend.com/article/0to8xcbzq8-integrate-clicksend-with-zapier)
## Blog posts
Your blog is a fantastic space for communicating updates to your Zapier integration.
For the most engaging posts, apply these best practices:
* **Explore new features** — Announce new Zapier features in your posts and give users ideas about how they can apply those features to their work.
* **Spotlight benefits** — Inspire users by directly referencing which apps they can connect to through Zapier and how those connections support their work.
*Example*: [Buffer](https://buffer.com/resources/buffer-zapier-integration/)
## Video tutorials
A well-made video can help break down complex ideas into easily digestible concepts—perfect for explaining Zapier to new users.
Here are two great starter videos you can create:
* **Welcome to Zapier** — Create an introductory video that walks users through a high-level overview of Zapier to help get them started.
* **Setup deep dive** — Break down the technical setup process in a thorough, engaging tutorial.
*Examples*: Adalo ([Intro video](https://www.youtube.com/watch?v=2IrXNEJkvcQ\&t=2s), [deep dive video](https://www.youtube.com/watch?v=nS4C7-7D14M\&t=1s))
# Add integration branding in Platform CLI
Source: https://docs.zapier.com/platform/publish/branding-cli
When you make a new integration in Zapier CLI, you can add the app's name, description, and homepage to the `package.json` file.
The rest of your app's branding needs to be added in Zapier's online Platform UI.
Focus first on building your integration. When you've added your app's core details, authentication, triggers, and actions, push your integration to Zapier with a `zapier push` command. Zapier will use the name you added in the CLI integration settings, along with a placeholder icon for your app.
Then, before launching your integration, add your app's branding via Zapier's Platform UI at [zapier.com/app/developer](https://zapier.com/app/developer). There you will see every Zapier integration you've built. The top *Integrations* section includes every app you've added via Zapier's Platform UI or CLI. Look for the integration you built with Zapier CLI and click its name.
You can't edit authentication, triggers, and actions in Zapier's Platform UI for integrations built with Zapier's CLI. But you can edit branding.
To do that, click the gear icon in the upper left hand corner near your app's name and placeholder icon. You can then edit your integration's name and description, and upload your app's icon (a square, transparent PNG at least 256x256px). Below that, you can set your app's category and other brand settings. Click *Update* to save your settings.
You can then make further changes to your integration in your Zapier CLI code and push them to Zapier anytime without affecting your branding. If you ever need to change your app icon or other branding again, just come back to the [Zapier Platform UI](https://zapier.com/app/developer) and edit it as before.
*→ Check [Zapier's app logo, name, and description guidelines](https://platform.zapier.com/partners/planning-guide#app-logo) to ensure your app's branding fits into the Zapier platform.*
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Integration branding guidelines
Source: https://docs.zapier.com/platform/publish/branding-guidelines
When creating your integration, you'll add your app’s name, logo, description, category, and primary brand color. Consistent branding is essential for helping users recognize and discover your app on Zapier.
The journey starts at the [Zapier app directory](https://zapier.com/apps/), where apps are ranked by popularity and category. Users search for new apps and integrations here.
Each integration gets its own app profile page on Zapier, where your branding stands out. Users can explore your app’s features and see how it works with other apps.
App profiles feature [Zap Templates](https://platform.zapier.com/publish/zap-templates)—pre-built workflows that users can set up with just a few clicks. These templates are also shown in the Zapier dashboard for connected apps.
Inside Zapier's account dashboard, the *Start with a template* section shows Zap Templates for apps users have connected to their accounts.
In the Zap editor, your app’s logo and name appear when users select apps to connect.
Follow these guidelines to ensure consistent, effective branding for your Zapier integration:
## App name
When possible, use your app’s current, public-facing name as it appears in your official branding. The app title on Zapier should match your actual app name, including correct capitalization and spacing. Do not include extra words or symbols like ™, ®, or © in the title.
Avoid adding adjectives, descriptors, or phrases unless required to distinguish between similarly named integrations. Only include your company name if it’s inseparably tied to your product branding.
Do not include the word “app” unless it is part of your official name. Abbreviations like FKA (formerly known as), AKA (also known as), and NKA (now known as) are not permitted. If your integration is rebranded, its title must use only the new name without referencing the previous name.
When naming collisions occur, i.e. when another integration already uses the same name, a tiered approach will be applied to distinguish your app while preserving brand clarity:
**Tier 1 (Preferred)**: App Name
Use this when your app name is unique across the Zapier platform and no other integration uses it. Examples:
* Evernote
* Google Sheets
* Trello
**Tier 2 (Next-best)**: App Name by Company
Use this if your app’s name is already taken and your company name is distinct from your product name. This helps differentiate between similar apps by clarifying the brand behind them. Examples:
* Ecwid by Lightspeed
* Bigin by Zoho CRM
* Grok by xAI
**Tier 3 (Last-resort)**: App Name (Descriptor)
Use this if both your app and company names are the same, and a name conflict exists. Add a short, descriptive tag that clearly differentiates your app. This could include your product’s category, function, or platform. Examples:
* Pulse (Business Chat)
* Pulse (Health Track)
* Nimbus (Notes & Docs)
* Nimbus (Weather)
## App logo
The logo you provide will be used across Zapier’s platform, including on your app’s dedicated directory page. Please ensure the logo you provide meets the following requirements:
* PNG, transparent
* Minimum 512x512px (identical height/width measurements)
* Minimum 72 DPI
This will ensure your logo displays properly throughout the site.
Please provide a bigger version if you have one available. If your icon is not square, make a square transparent image and center your icon inside the transparent square. Do not include the app name or other copy in the logo as it will not be legible at small sizes.
**Example**:
Evernote's elephant icon is included in a transparent square rectangle.
Todoist's icon includes transparent, rounded corners.
## App description copy
Write a short description (up to 160 characters) of your app’s core features and use cases in the form of "**Integration Name** is a....". The description should be less about selling the platform and more about what the platform actually does. Use proper English and full sentences. The copy should not include links or mentions of Zapier. Do not use flowery or overstated language, or make it appear your integration is associated with or endorsed by Zapier.
**Example**:
* `Trello is a team collaboration tool to organize anything on a kanban board.`, not `Trello is the best project management tool.`
* `Dropbox lets you store files online, sync them to all your devices, and share them easily.`, not `A file storage app.`
## Category
Select the category that best fits your app's core features and use case. If your app includes features from multiple categories, choose the category that best describes your app's primary use case today.
Can't find an existing category that represents your app? Let us know! Suggest a category you'd like to see added to our app directory by [submitting this form](https://integration-branding.zapier.app/suggest).
You may update your app's category in the future if needed, so do not select a category that fits your future ambitions for the app instead of its features today. Additionally, do not select a category that applies only to a secondary feature in your app or a narrow category that does not cover your app's broader focus.
### Available Categories
We offer a variety of categories for you to list your integration in. Each top-level category includes all integrations from its child categories. To maximize visibility for your integration, we recommend selecting a specific child category rather than a general parent category. Integrations within each category are ranked by popularity. By choosing a child category, your integration can achieve a higher ranking and greater visibility within that category.
* Artificial Intelligence - Tools that offer AI features such as natural language processing, image classification, and more.
* AI Tools - Tools to unlock AI potential in your workflow.
* Business Intelligence - Tools to gather, analyze, and visualize business data.
* Analytics - Tools to measure and report on success.
* Dashboards - Tools to view your data on a full-screen dashboard.
* Reviews - Tools to manage your reviews and ratings.
* Commerce - Tools to facilitate all aspects of business transactions, both online and offline.
* Taxes - Tools for automating your taxes.
* Accounting - Tools for accounting and finance.
* eCommerce - Tools to sell your products online.
* Fundraising - Tools to set up fundraising events and projects.
* Payment Processing - Tools to process payments on your site or app.
* Proposal & Invoice Management - Tools to create and send proposals and invoices to clients.
* Communication - Tools to streamline and enhance communication across various channels.
* Call Tracking - Tools to monitor calls and track data from non-digital marketing campaigns.
* Email - Tools to manage your personal and business email correspondence.
* Fax - Tools to send documents over fax.
* Notifications - Tools to get customized notifications on your computer or mobile devices.
* Phone & SMS - Tools to make calls and send SMS messages.
* Team Chat - Tools to help teams collaborate together online with real-time chat.
* Team Collaboration - Tools for business social networking, file sharing, and chat to help teams work together more effectively.
* Video Conferencing - Tools to host team video calls and webinars.
* Content & Files - Tools to create, manage, and share various types of content and files.
* Documents - Tools to write, edit, and share text documents.
* File Management & Storage - Tools to organize, share, and sync files.
* Images & Design - Tools for creatives and those dealing with images.
* Notes - Tools to write down thoughts and organize them in notebooks.
* Transcription - Tools to transcribe audio into text.
* Video & Audio - Tools to store and share multimedia assets.
* Human Resources - Tools to manage all aspects of human resources, from hiring and recruitment to employee management and development.
* Education - Tools to enhance learning and teaching experiences
* HR Talent & Recruitment - Tools to manage your hiring and human resource department.
* Internet of Things - Tools to connect and manage IoT devices and services.
* Devices - Tools for connecting Internet of Things devices through Zapier.
* Printing - Tools to print your designs, either on your printer or on products such as t-shirts and stickers.
* IT Operations - Tools to manage and optimize IT infrastructure and services.
* Databases - Tools for developers to store and manage data.
* Developer - Tools to build and maintain software, services, and websites.
* Online Courses - Tools to publish lessons and educational material.
* Security & Identity - Tools to manage security and identity/permissions
* Server Monitoring - Tools that monitor services and application metrics.
* Lifestyle & Entertainment - Tools to enhance various aspects of your personal life and leisure activities.
* Fitness - Tools to track your workouts, food, and more.
* Gaming - Tools that are centered around video gaming.
* News & Lifestyle - Tools to keep you informed on news and lifestyle content.
* Marketing - Tools to plan, execute, and measure marketing campaigns across various channels.
* Ads & Conversion - Tools to track and reach an audience online.
* Drip Emails - Tools to send automated email messages on a set schedule.
* Email Newsletters - Tools to send regular email updates and newsletters to your subscribers.
* Event Management - Tools to manage events and attendees.
* Marketing Automation - Tools to market products, track interests, and turn visitors into customers.
* Social Media Accounts - Tools to connect and share with others online.
* Social Media Marketing - Tools to automatically share posts on social networks.
* Transactional Email - Tools to send email messages through your application.
* URL Shortener - Tools to shorten URLs.
* Webinars - Tools for scheduling and holding webinars.
* Productivity - Tools to enhance efficiency and organization in your personal and professional life.
* Bookmark Managers - Tools to save your favorite links to view and read later.
* Calendar - Tools to plan your events and schedule.
* Product Management - Tools to plan your product's lifecycle and roadmap.
* Project Management - Tools for managing projects.
* Spreadsheets - Tools to manage numbers and data.
* Task Management - Tools to manage your tasks on simple lists.
* Time Tracking Software - Tools to track time spent on work and projects.
* Sales & CRM - Tools to manage and optimize your sales processes and customer relationships.
* Contact Management - Tools to keep track of the people you need to keep in touch with most.
* CRM (Customer Relationship Management) - Tools for customer relationship management.
* Forms & Surveys - Tools to build forms and gather data from your website or apps.
* Scheduling & Booking - Tools to schedule appointments and events.
* Signatures - Tools to manage and sign legal documents online.
* Support - Tools to enhance customer satisfaction and provide effective assistance.
* Customer Appreciation - Tools that help you show appreciation to your customers.
* Customer Support - Tools to answer your customers' questions through email, chat, and documentation.
* Website & App Building - Tools to create and customize websites and applications.
* App Builder - Tools to build a custom app with forms and databases.
* Website Builders - Tools to help manage content and build websites for your business.
**Example**:
* *Gmail* is primarily an app to send and receive email messages, so it fits best in the `email` category alongside services like *Microsoft Office 365*, not in the `email newsletters` category with *Mailchimp*.
* *Slack* is primarily a team communication tool for chat, so it fits best in the `team chat` category alongside apps like *Discord* and *ChatWork*, not in the `video calls` category even though it does include a video call tool as a secondary feature.
* *Google Contacts* is primarily an address book that fits best with other `contacts` apps, while *HubSpot CRM* can manage contacts but also includes deals and contact tracking which makes it a better fit for the `CRM` category.
## Colors
When you release your Zapier integration to the public, Zapier requires your app's primary color. The primary color is the main color used in your app's logo or branding.
Do not use pure white (`#FFFFFF`) as the color, as overlaid text would be unreadable. If your logo is black and white, use the next most common color from your branding.
Zapier uses the primary color as the background color in your app's Zapier App Directory listing, and may additionally use it in the Zapier app dashboard, Zapier blog marketing materials, and other parts of Zapier's app and content that promote your app's integrations.
## Frequently Asked Questions
Currently, we only allow 1 category per integration^. This is to maintain our categorization effectiveness, making it easier for users to find relevant integrations. Limiting integrations to 1 category also helps to improve your discoverability within the category.
*^Additional categories are limited to App Families and AI Tools at Zapier's discretion*
Yes, you can. Submit the Rebrand Form located at the top of the Settings page for your integration in the [Developer platform](https://developer.zapier.com).
An app family refers to a collection of related integrations, typically developed by the same organization. Being added to an App Family is at the discretion of Zapier.
Being classified as a Premium app isn't something we currently offer to partner-owned integrations. The justification as to why a Zapier-owned integration might be classed as Premium varies, but is often due to an increased cost on our end to be able to offer that integration. Only users on a paid Zapier plan can use Premium integrations, which helps to ensure we can continue to invest in the development of that integration.
[Submit this form](https://integration-branding.zapier.app/suggest) to suggest a new category. Our team will review all submissions for consideration. If we move forward with adding your suggestion as a category, we'll notify you via email.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Integration build guidelines
Source: https://docs.zapier.com/platform/publish/integration-build-guidelines
Before publishing your integration on Zapier, it is essential to ensure that your integration is well-prepared to provide a seamless and efficient user experience. The following guidelines are designed to assist you in refining your integration before submitting it for review. Adhering to these guidelines will help enhance the functionality and user interaction with your integration and will provide you with the best value and opportunities to harness Zapier as a method of obtaining new users and most commonly, boosting the lifetime value of your current customers.
## Familiarization and testing
### Familiarize yourself with Zapier
If new to Zapier, start by signing up for a free account and experimenting with [popular integrations](https://zapier.com/apps). This will help you understand how Zapier works, how your users will set up Zaps, and how your integration can best fit into Zap workflows
### Identify key use cases
Focus on the primary functionalities of your application. Review similar integrations in [Zapier's App Directory](https://zapier.com/apps) and [recommended features](/platform/quickstart/must-have-triggers-and-actions) by app category for ideas on which items to include in your integration. Also, get feedback from your current customer base on their needs and wants from automation with your application.
### Thorough integration testing
* **Internal Testing**: Develop and test Zaps using your integration's triggers, actions, and searches in your Zapier account. Ensure these are error-free and have successful runs in the Zap History. This gives you firsthand experience of the Zap setup process our mutual users will go through.
* **External Testing**: [Share your integration](/platform/manage/sharing) with external users before submitting it for review to gather early feedback from them and make changes to the integration when necessary.
### Provision of demo accounts and resources
Provide access to a fully functional demo account and any necessary resources to facilitate the review process.
### Automatic validation checks
Review the [integration check reference documentation](/platform/publish/integration-checks-reference) while building your integration to pass the automatic validation when submitting for publishing. To publish your integration, all Errors and Publishing Tasks must be validated. Warnings are non-blocking and not strictly required to proceed as they would not prevent you from promoting a version, though we do recommend you review them for the usability of your integration.
## Integration information
### Comprehensive documentation and metadata
All integration information, including the name, logo, description, and category, should be complete, accurate, and adhere to [Zapier's branding standards](/platform/publish/branding-guidelines). If your app includes features from multiple categories, choose the category that best describes your app's primary use case today.
### Clarify non-obvious features
Detail any complex features in your publishing request notes, and include relevant documentation to support understanding and review.
### Consistency in style and branding
The terminology and features in your Zapier integration should be consistent with the terminology and features seen in your product's UI. We strive to give users a consistent experience throughout Zapier, so your integration should also be consistent with the style used in other popular Zapier integrations. Be sure to follow Zapier's integration branding and design requirements to ensure your integration suits the Zapier ecosystem well.
## Authentication
### Ease of connecting accounts
Simplify the authentication process, preferably using [OAuth v2](/platform/build/oauth). For non-OAuth v2 authentication schemes, users must be able to easily generate and retrieve API keys and/or other required credentials themselves without needing assistance from your support team.
### Help texts
Provide help texts for authentication fields with guidance on where users can find their credentials if you're not using Basic Auth. If possible, provide an embedded [link](https://www.markdownguide.org/basic-syntax/#links) using [Markdown](https://www.markdownguide.org/) in the help text straight to the page in the platform where users can find the credentials. For example, “Go to the [API details](https://my.xxxx.com/manage/api-details) screen from your Dashboard to find your API Key.“
### Input format
If authenticating to your app requires providing a value in a certain format (such as a sub-domain URL), you should specify this format with the Input Format option when adding the input field for this value.
### Handling invalid credentials
Return informative and user-friendly error messages for authentication issues. For example, “Your API Key does not appear to be valid.” is better than a generic 401 error message.
## Triggers
### Trigger design and copy
Any copy associated with a trigger should match the copy, text, and terminology used in your product's UI. This includes the trigger's name, description, input fields, help text, output fields, etc. For instance, since Dropbox calls directories “folders” in their product UI, the respective trigger in [their Zapier integration](https://zapier.com/apps/dropbox/integrations#triggers-and-actions) refers to “folders” instead of “directories”. If your API uses different terminology than your product's UI, match the UI as users are most familiar with this - not the API.
Additionally, each trigger must have:
* a descriptive, titlecased name. For example, ‘New Lead', instead of ‘New lead'.
* a descriptive key. For example, ‘new\_lead', instead of ‘trigger\_1'.
* a descriptive noun that reflects the object that is being returned in the trigger. This typically is one word and should always be in the singular form. The noun is used around the Zapier platform and will be pluralized automatically to complete various messages to users such as ‘No new X found.‘
* a concise description using our standard phrasing ‘Triggers when…“ and no more than a handful of additional words. Always the description with a period/full-stop. Do not include the name of your integration nor capitalize the noun in the description such as ‘Triggers when a new Lead is created in Example CRM.'
### Trigger input fields
[Trigger input fields](/platform/build/add-fields), if they exist, should be named appropriately and include help text if their purpose is ambiguous. Use appropriate naming, ordering, and field types. Avoid unnecessary complexity in ID fields and include helpful tooltips where necessary.
* **ID fields**: Users should never be expected to type in an ID as this is error prone. Your integration should not have any trigger fields labeled ‘ ID', such as ‘Customer ID'. Instead, use Zapier's dropdown functionality to provide users with a user-friendly list of options.
* **Help texts**: Don't be redundant with help text, and only include it if you have something different to say from the field name such as the expected format of the value or additional instructions that would aid users in knowing what value the field expects and sometimes, how they can get those values. Redundant help text teaches users not to read any help text at all, so important information can be missed. Use [Markdown](https://www.markdownguide.org/) to [format text](https://www.markdownguide.org/basic-syntax/#emphasis) and include [links](https://www.markdownguide.org/basic-syntax/#links) to more detailed help documentation created on your site where applicable.
* **Optional trigger fields**: If a trigger field is optional, confirm the request does not throw an error in a null case where the user does not select an option.
* **Field types**: Use the most appropriate [input field type](/platform/build/add-fields) for each of the input fields to show users what type of data to include. Note the Zap editor does not validate the data to ensure users added the correct item for that field type. If the field can accept multiple values, use our built in [‘List' property](https://github.com/zapier/zapier-platform/blob/main/packages/schema/docs/build/schema.md#fieldschema) or ‘[Allow Multiples](/platform/build/add-fields#allows-multiples)' functionality rather than asking users to provide a comma-separated value in a text field.
* **Ordering**: Put required trigger input fields at the top of the form with optional fields towards the bottom by importance.
### Static webhook
Triggers using static webhooks are not allowed in public Zapier integrations. Users can replicate this functionality in their Zaps via the [Webhooks by Zapier Integration](https://zapier.com/apps/webhook/integrations). Please consider including authentication and using REST Hooks to provide users with a more streamlined experience.
### Polling triggers
Live Zaps with [polling triggers](/platform/build/trigger) automatically poll the request URL for new data every 1 to 15 minutes, depending on the user's [Zapier plan](https://zapier.com/pricing). For an effective polling trigger, the following should be done:
* Return results from the polling URL in reverse chronological order by created date, so the most recently created or updated object is returned first.
* Return a sufficient amount of items from the polling endpoint. Generally, 100 items is plenty for most integrations, but there are cases where it's common for users to perform an action in your app that would trigger more than 100+ records at once. Note that a trigger with more than 100 new items returned in a poll will run into the [polling trigger throttle](/platform/build/operating-constraints#polling-trigger-throttle-zapier).
* Use [pagination](/platform/build/pagination-trigger) on trigger results when being used to populate a dynamic dropdown, if large amounts of data will be returned.
* Each result should contain a unique primary key (usually an id field) for [deduplication](/platform/build/deduplication) from the polling endpoint.
### REST hook
[REST hook-based triggers](/platform/build/trigger) are Zapier's preferred implementation of triggers since they fire immediately after the triggering action is performed.Our mutual users prefer REST hook triggers over polling triggers in their Zaps. They are labelled as [Instant triggers](https://help.zapier.com/hc/en-us/articles/8496244568589-Types-of-triggers-in-Zaps) to users For an effective REST hook trigger, the following should be done:
* Hook-based triggers must allow multiple subscriptions without overwriting subscriptions. You can test this by setting up 2 Zaps with the same trigger, turning them On, and confirming both Zaps fire successfully when the triggering event is performed in your app.
* Each REST Hook trigger must also have a polling URL defined in the Perform List. This allows users to easily pull in sample resources to set up their Zaps without leaving the Zap editor. Without a corresponding polling URL, users would have to navigate off of the Zap editor to the product to create or update a resource each time they set up a Zap. Ensure that the data returned from the polling URL follows the Polling Trigger requirements above.
* Data returned from the polling URL should exactly match the data returned in the hook payload. Check that field keys from the polling URL and in the hook payload match in spelling, casing, and data structure.
### Response content
The response content is what is returned to Zapier by the trigger. The response data should include important keys in the most usable format. For example, it helps to return both the ID and pretty name of objects, any contact information, and links to the resource (ex: for a New Card in Trello trigger, a URL to link to card). Remove unnecessary fields that may seem confusing or add noise to users' Zap setup process. For example, if the response content includes information about the request itself and the input fields provided, please remove those fields from the returned response. Also, ensure that the response content meets the below guidelines
* **Names**: Many actions in Zapier require names to be split into two fields - first/last or given/surname. This conflicts with some naming schemes around the world, but without separated name fields, your trigger may not be compatible with certain integrations. Always provide separate name fields, though feel free to return the full name as well if the response already includes this.
* **Addresses**: Likewise with names, many actions in Zapier require address components in separate fields (street, street2, city, state, zip), instead of requiring the complete address in a single field. Always provide separated address fields, though feel free to return the complete address as well if the response already includes this.
* **Date-times**: Date-time values are required to be in [ISO 8601 format](http://www.cl.cam.ac.uk/~mgk25/iso-time.html?utm_source=zapier.com\&utm_medium=referral\&utm_campaign=zapier#date) and should always include a time zone offset (even if it is UTC). This includes date-time values returned from the polling URL, in the hook payload, and your sample data. Avoid UNIX/Epoch timestamps. Date-time values may be modified in your API call custom code if your API returns dates in different formats. Example acceptable date-time values include:
* `2023-12-15T01:15:13Z` (or `-0000` instead of `Z`)
* `2023-12-01T12:32:01-0800`
* `2023-12-01T12:32:01-08:00`
* `2023-12-13` (for date-only values)
* **Booleans**: Set boolean values as true or false. Do not use 1 and 0 or alternative representations for boolean values.
* **Dropdown fields**: Return both the name and ID of the selected dropdown option to be used in subsequent steps of a Zap.
### Sample data
Each trigger requires [sample data](/platform/build/sample-data) for instances where no result is returned during Zap setup or the user chooses to skip testing. This could be because the API is temporarily down, or because the user has no existing data in their account to return. The sample data must:
* Only represent one item, and not the entire response of the request if there are multiple items returned as a set. For example, \{“key”: “value”} instead of \[\{“key”: “value”}, \{“key”: “value2”}, … ].
* Use representative data in the expected format the values will be returned. For example, don't set a ‘first name' key to a value of ‘string' or ‘1234'; set it to something like ‘Bob'.
* Only return the keys that would be returned in every response for all users of the trigger. This means if there are custom fields that will be returned for some users and not others, please do not include these in the sample data.
### Output fields
[Output fields](/platform/build/sample-data) add user-friendly labels to your API's response to facilitate mapping fields during Zap setup for users. By default, Zapier will try to make a friendly version of the response by capitalizing words and replacing underscores with spaces, but this can be customized. Add a custom output field label when:
* a field is abbreviated. For example, ‘LTV' should be labeled ‘Lifetime Value'.
* a field has an ambiguous unit of measure. For example, ‘Duration' should be labeled ‘Duration (in seconds)'.
* a field is represented by an ID.
* in general, it is not instantly clear what the field or value represents.
### Update triggers
Don't offer a generic ‘Updated ' trigger, as these are often too general for users to use in their Zaps. Instead, think under what specific scenarios the user needs an update trigger. For example, instead of offering an ‘Updated Deal' trigger which triggers when anything changes on the deal, offer a ‘New Deal in Stage' or ‘Updated Deal Status' trigger that allows the user to specify which stage they want to monitor.
### Error messages
Users should never receive a success/200 response if there was an error in the request as this will not show up as an error in the Zap history. All error messages should be user-friendly and avoid technical jargon. Be as specific as possible to what caused the error.
## Actions
### Action design and copy
The copy for actions should match your product's UI. This includes the action's name, description, input fields, help text, etc. For instance, since Dropbox calls directories “folders” in their product UI, the Zapier integration should refer to “folders” in the respective action. If the API uses different terminology than your product's UI, match the UI - not the API.
Additionally, each action must have:
* a descriptive, titlecased name. For example, ‘Create Lead', instead of ‘Create lead'.
* a descriptive key. For example, ‘create\_lead', instead of ‘action\_1'.
* a descriptive noun that reflects the object that is being created or updated in the action. This should typically be one word and should always be in the singular form. The noun is used around the Zapier platform and will be pluralized automatically to complete various messages to users such as ‘No new found.‘
* a concise description starting with a plural form of the action verb, and ending in a period/full-stop. For example, the description for a ‘Create Lead' action could be ‘Creates a new lead.' Please do not include the name of the platform nor capitalize the noun such as ‘Creates a new Lead in XXX CRM.'
### Action input fields
All action steps must include [input fields](/platform/build/add-fields) to gather the data needed to create, update, or perform the intended action. These fields should be named appropriately and include help text if their purpose is ambiguous. Use appropriate naming, ordering, and field types. Avoid unnecessary complexity in ID fields and include helpful tooltips where necessary.
* **ID fields**: Users should never be expected to manually type or map an internal ID to an action field. Your integration should not have input fields labeled ‘XXX ID'. Generally, trigger and action steps of other integrations do not return internal IDs for your specific platform to be used in an action field from your Zapier integration. Use Zapier's [dynamic dropdown](/platform/build/add-fields#dynamic-dropdown) and [Search Connector](/platform/build/add-fields#dynamic-dropdown:~:text=**%203.Add%20search%20to%20a%20dynamic%20field%20\(optional\)**)/[search-powered field](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#how-do-search-powered-fields-relate-to-dynamic-dropdowns-and-why-are-they-both-required-together) functionalities to provide users with an easier way to select or search for the appropriate resource by a more readily available value such as ‘name', ‘email address', ‘title', etc.
* **Ordering**: Order action fields logically. If you are unsure, look at how the respective fields are ordered in your platform and mimic that since users will be familiar with that ordering. Required action fields should generally be listed first at the top of the Zap editor while all optional, lesser-used fields towards the bottom. Group related fields together. For example, first name and last name fields, as well as individual address component fields should be ordered consecutively. Do NOT use [line-item groups](/platform/build/line-items) or the ‘[children](https://github.com/zapier/zapier-platform/blob/main/packages/schema/docs/build/schema.md#fieldschema)' field schema key to visually group fields; these are solely intended for line-item or array functionality.
* **Required fields**: If a field is not required by your API, don't make it required in the Zap action. Parallel the required fields from your integration as closely as possible. For example, if ‘Email Address' is not required to create a lead in the platform, do not make the ‘Email Address' field required in the Zap editor. If the API specifies a non-important field as required, hard-code a default value so the field is not empty if one is not provided by the user. If the action step has a case where one field OR another field is required, set both fields as optional, add help text to both fields stating that one or the other is required, and throw a user-friendly error message if neither field is filled.
* **Help texts**: Don't be redundant with help text, and only include it if you have something different to say from the field name such as the expected format of the value or additional instructions. For example, help text for an ‘Email Address' field stating ‘Contact's email address' is not necessary. Redundant help text teaches users not to read any help text at all, so important information can be missed. Use [Markdown](https://www.markdownguide.org/) to [format text](https://www.markdownguide.org/basic-syntax/#emphasis) and include [links](https://www.markdownguide.org/basic-syntax/#links) to more detailed help documentation created on your site where applicable.
* **Default values**: Set [default values](/platform/build/add-fields) for input fields sparingly. If the API specifies an unimportant field as required, set a default value in case one is not provided by the user. If the field in the application is set to or shows a default value, set the same default value for the action field in the Zapier integration.
* **Field types**: Use the most appropriate [input field type](/platform/build/add-fields) for each of the input fields to show users what type of data to include — note Zapier does not validate the data to ensure users added the correct item for that field type. If the field can accept multiple values, use our built-in [‘List' property](https://github.com/zapier/zapier-platform/blob/main/packages/schema/docs/build/schema.md#fieldschema) or ‘[Allow Multiples](/platform/build/add-fields#allows-multiples)' functionality rather than asking users to provide a comma-separated list of values in a text field.
### Response content
Return information about the resource that was created, updated, or affected by the action, and not just a ‘success' message. At a minimum, return an ID, the name or title of the resource (when pertinent), and a link to the newly created, updated, or affected resource in the platform (if available). Additionally, return any other useful data about the resource users may need in subsequent actions of a multi-step Zap.
* **Date-times**: Date-time values are required to be in standard [ISO 8601 format](http://www.cl.cam.ac.uk/~mgk25/iso-time.html?utm_source=zapier.com\&utm_medium=referral\&utm_campaign=zapier#date) and should always include a time zone offset (even if it is UTC). This includes date-time values returned in the response content and in your sample data. Avoid UNIX/Epoch timestamps. Date-time values may be modified in your API call custom code if your API returns dates in different formats. Example acceptable date-time values include:
* `2023-12-15T01:15:13Z` (or `-0000` instead of `Z`)
* `2023-12-01T12:32:01-0800`
* `2023-12-01T12:32:01-08:00`
* `2023-12-13` (for date-only values)
* **Booleans**: Set boolean values as true or false. Do not use 1 and 0 or alternative representations for boolean values.
* **Important Data**: The response data should include important fields in the most usable format. For example, it helps to return both the ID and pretty name of resources, any important information about the resource such as contact information, and a link to the resource in the platform (ex: Create Card in Trello action returns a URL link to the card created). Also, Returning a link to the newly created/updated/affected resource in the action's response data helps users link to the resource in subsequent steps of a multi-step Zap and confirms the new resource was created. This is also helpful for the Zapier support team when debugging issues.
* **Unnecessary/Excess Data**: Remove non-necessary fields that may seem confusing or add unnecessary noise to users' Zap setup process from your API call's custom code. For example, if the response content includes information about the request itself and the input fields provided, please remove those fields from the returned response.
* **Dropdown Fields**: Return both the name and ID of the selected dropdown option to be used in subsequent steps of the Zap.
### Sample data
The ‘Test' step on actions sends a real request on behalf of the connected account. Therefore, each action requires [sample data](/platform/build/sample-data) for instances when the user does not wish to actually run the action in their account to finish setting up the Zap. The sample data must:
* Represent the expected return from the request when a record is successfully created or found.
* Use representative data in the expected format the values will be returned. For example, don't set a ‘first name' key value to ‘string' or ‘1234'; set it to something like ‘Bob'.
* Reflect the keys returned in every response for all users of the action. This means if there are custom fields that will be returned for some users and not others, please do not include these key:values in the sample data.
### Output fields
[Output Fields](/platform/build/sample-data) add user-friendly labels to your API's response data to facilitate mapping fields during Zap setup for users. By default, Zapier will try to make a friendly version of your API's response, capitalizing words, and replacing underscores with spaces, but they can also be customized. Add a custom output field label when:
* a field is abbreviated. For example, ‘LTV' should be labeled ‘Lifetime Value'.
* a field has an ambiguous unit of measure. For example, ‘Duration' should be labeled ‘Duration (in seconds)'.
* a field is represented by an ID.
* in general, it is not instantly clear what the field or value represents.
### Create or update functionality
If your integration must have a ‘Create-or-Update' functionality, implement a ‘Search-or-Create' with an ‘Update' action versus a ‘Search' with a ‘Create-or-Update' action or a standalone ‘Create-or-Update' action.
### Delete actions
Carefully consider delete actions that fully delete or remove data. To prevent data loss, action steps should preferably only add or update data.
If you have a valid use case for a delete action, consider alternative actions for items such as deactivating, unsubscribing, or canceling, instead of deleting items completely.
If you do add a delete action, make sure to include a Copy field to clarify to users that the action is irreversible once the API request is made.
### Error messages
Users should never receive a success/200 response if there was an error in the request as this will not show up as an error in the Zap history. All error messages should be user-friendly and avoid technical jargon. Be as specific as possible to what caused the error.
## Searches
### Find or create
Search actions can optionally create items if nothing is found in the search. If your integration has a ‘Create-or-Update' action, please implement a ‘Search-or-Create' with an ‘Update' action versus a ‘Search' with a ‘Create-or-Update' action or a standalone ‘Create-or-Update' action.
### Search design and copy
The copy for searches should match your product's UI. This includes search name, description, input fields, help text, etc. For instance, since Dropbox calls directories “folders” in their product UI, the Zapier integration should refer to “folders” in the respective search. If the API uses different terminology than your integration's UI, match the UI - not the API.
Additionally, each search must have:
* a descriptive, titlecased name. Use ‘Find' over ‘Get'. For example, ‘Find Lead', instead of ‘Get Lead'.
* a descriptive key. For example, ‘find\_lead', instead of ‘search\_1'.
* a descriptive noun that reflects the object that will be returned. This should typically be one word and should always be in the singular form. The noun is used around the Zapier platform and will be pluralized automatically to complete various messages to users such as ‘No new found.‘
* a concise description starting with a plural form of the verb, which typically is ‘Finds', and ending in a period/full-stop. For example, a valid description for a ‘Find Lead' search is ‘Finds a new lead.' Please do not include the name of the platform nor capitalize the noun such as ‘Finds a new Lead in XXX CRM.'
### Search input fields
[Search input fields](/platform/build/add-fields) should be named appropriately and include help text if their purpose is ambiguous.
* **ID fields**: Users should never be expected to manually type or map an internal ID to a search field. Your integration should not have search fields labeled ‘XXX ID'. Trigger and action steps of other integrations do not return internal IDs for your specific app that could be used in an action field for your Zapier integration. If the user is using a trigger from your Zapier integration, the trigger should return all necessary information about the resource without the Zap needing a search step to retrieve additional, necessary information. Instead, provide search field options for more general information such as ‘name', ‘email address', ‘phone number', ‘title', etc. that is more readily available from all triggers.
* **Ordering**: Put required search fields at the top of the form with optional fields towards the bottom by importance.
* **Optional search fields**: If a search field is optional, confirm the request does not throw an error in a null case where the user does not select an option.
* **Help texts**: Don't be redundant with help text, and only include it if you have something different to say from the field name such as the expected format of the value or additional instructions. Redundant help text teaches users not to read any help text at all, so important information can be missed. Use [Markdown](https://www.markdownguide.org/) to [format text](https://www.markdownguide.org/basic-syntax/#emphasis) and include [links](https://www.markdownguide.org/basic-syntax/#links) to more detailed help documentation created on your site where applicable.
* **Field types**: Use the most appropriate [input field type](/platform/build/add-fields) for each of the input fields to show users what type of data to include — note Zapier does not validate the data to ensure users added the correct item for that field type. If the field can accept multiple values, use our built-in [‘List' property](https://github.com/zapier/zapier-platform/blob/main/packages/schema/docs/build/schema.md#fieldschema) or ‘[Allow Multiples](/platform/build/add-fields#allows-multiples)' functionality rather than asking users to provide a comma-separated list of values in a text field.
### Response content
While “create” actions return a single object to Zapier; searches must return an array of objects. Each search must follow these requirements:
* **No Result**: Do not raise an error if there are no search results to return. If your API returns a 404 for search misses, use custom code to [return a 200 with an empty array as the response](/platform/build/response-types).
* **Names**: Many actions in Zapier require names to be split into two fields - first/last or given/surname. This conflicts with some naming schemes around the world, but without a separated name field, your action may not be compatible with certain integrations in subsequent steps of a user's Zap. Always provide separated name fields if applicable, though feel free to return the full name as well if the response already includes this.
* **Addresses**: Likewise with names, most actions in Zapier require address components in separate fields (street, street2, city, state, zip), instead of requiring the complete address in a single field. Always provide separated address fields, though feel free to return the complete address as well if the response already includes this.
* **Date-times**: Date-time values are required to be in standard [ISO 8601 format](http://www.cl.cam.ac.uk/~mgk25/iso-time.html?utm_source=zapier.com\&utm_medium=referral\&utm_campaign=zapier#date) and should always include a time zone offset (even if it is UTC). This includes date-time values returned in the response content and in your sample data. Avoid UNIX/Epoch timestamps. Date-time values may be modified in your API call custom code if your API returns dates in different formats. Example acceptable date-time values include:
* `2023-12-15T01:15:13Z` (or `-0000` instead of `Z`)
* `2023-12-01T12:32:01-0800`
* `2023-12-01T12:32:01-08:00`
* `2023-12-13` (for date-only values)
* **Booleans**: Set boolean values as true or false. Do not use 1 and 0 or alternative representations for boolean values.
* **Important Data**: The response data should include important fields in the most usable format. For example, it helps to return both the ID and pretty name of resources, any important information about the resource such as contact information, and a link to the resource in the platform (ex: Find Card in Trello search, returns a URL link to the found card).
* **Unnecessary/Excess Data**: Remove unnecessary fields that may seem confusing or add noise to users' Zap setup process from your API call's custom code. For example, if the response content includes information about the request itself and the input fields provided, please remove those fields from the returned response.
### Sample data
Each search requires [sample data](/platform/build/sample-data) for instances where no result is returned during Zap setup. This could be because the API is temporarily down, or because no result is returned for the specific search the user tests. The sample data must:
* Only represent one record, and not the entire return from the request if there are multiple records returned as a set. For example, \{“key”: “value”} instead of \[\{“key”: “value”}, \{“key”: “value2”}, … ].
* Use representative data in the expected format the values will be returned. For example, don't set a ‘first name' key value to ‘string' or ‘1234'; set it to something like ‘Bob'.
* Reflect keys available in every response for all users of the search. This means if there are custom fields that will be returned for some users and not others, please do not include these key:values in the sample data.
### Output fields
[Output fields](/platform/build/sample-data) add user-friendly labels to your API's response data to facilitate mapping fields during Zap setup for users. By default, Zapier will try to make a friendly version of your API's response, capitalizing words, and replacing underscores with spaces, but they can also be customized. Add a custom output field label when:
* a field is abbreviated. For example, ‘LTV' should be labeled ‘Lifetime Value'.
* a field has an ambiguous unit of measure. For example, ‘Duration' should be labeled ‘Duration (in seconds)'.
* a field is represented by an ID.
* in general, it is not instantly clear what the field or value represents.
## Error handling
APIs are not always available. Users do not always provide valid data for requests. Build a defensive and resilient integration. Plan for 4xx and 5xx responses. Without [proper handling](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#error-handling), errors can have incomprehensible messages, technical error codes, or remain unnoticed by users.
### General errors
Use `z.errors.Error` in situations where users misconfigure their Zaps and need to take action. Typically, this will be for prettifying `4xx` responses and APIs that return errors as 200 with a payload that describes the error with guidance on how to correct it.
* If a Zap raises too many error messages it will be [automatically turned off](https://help.zapier.com/hc/en-us/articles/8496037690637-Troubleshoot-errors-in-Zapier#500-series-error-codes-0-3), so only throw these if the scenario is truly an error that needs to be fixed.
* Elaborate on terse messages. ‘Your API Key is invalid.' is better than ‘not\_authenticated.'
* If the error calls out a specific field, surface that information to the user. ‘Title is not valid.' is better than ‘Invalid Request.'
* If the error provides details about why a field is invalid, surface that information to users. ‘Title is invalid. Please only use alphanumeric characters.' is better than ‘Title is invalid.‘
### Halting errors
Use `z.errors.HaltedError` in situations where a required pre-condition is not met. For instance, in an action to add an email address to a list where duplicates are not allowed, throw a `HaltedError` if the Zap attempted to add a duplicate. This indicates failure but is treated as a soft failure. Thus, unlike general errors, a Zap will never be turned off when this error is thrown even if it is raised more often than not.
### Stale authentication credentials
For integrations requiring a manual refresh of authorization regularly, Zapier provides `z.errors.ExpiredAuthError`, so the current operation is interrupted, the Zap is turned off (to prevent additional runs with expired credentials), and a predefined email is sent out informing the user to refresh the credentials. The runs will be [Held](https://help.zapier.com/hc/en-us/articles/20505304170637-Review-Zap-run-statuses), and the user will be able to replay them after reconnecting.
For integrations using OAuth2 with automatic refresh requests or Session Auth, use `z.errors.RefreshAuthError`. This signals Zapier to refresh the credentials and retry the failed operation.
## Code quality
### Environment variables
Do not hard code credentials such as API Keys, Client IDs, Client Secrets, etc. into your integration. Use [environment variables](/platform/build/env) instead.
### Structure
If you are using the [Zapier CLI](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md) to build the integration, ensure files are logically broken out into respective directories and the code is easy to follow. We suggest putting triggers, actions, and searches each in their directories.
### Dependencies
If you are using the [Zapier CLI](/platform/reference/cli-docs), keep dependencies up to date. When notified that a dependency must be updated—for example, `zapier-platform-legacy-scripting-runner`, `zapier-platform-core`, or `zapier-platform-cli` —complete the update promptly or by the stated deadline. If requested updates are not completed by the stated deadline, Zapier reserves the right to make necessary updates on your behalf.
## Conclusion
While these guidelines are not exhaustive, they provide a robust framework to prepare your integration for a successful launch on Zapier.
Note that while not implementing these guidelines would not prevent your integration from being published, there are certain [requirements](/platform/publish/integration-publishing-requirements) that **must** be met before your integration can be approved for publishing.
For any specific questions or additional support, feel free to contact the Developer Support team at Zapier via the [contact form](https://developer.zapier.com/contact).
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Integration check reference
Source: https://docs.zapier.com/platform/publish/integration-checks-reference
Before you can submit your integration for publishing, it runs through a set of automated checks to ensure it's working properly and giving our users (and yours) the best possible experience.
To [publish your integration](/platform/publish/public-integration), all Errors and Publishing Tasks must be validated. Warnings are non-blocking and not strictly required to proceed as they would not prevent you from promoting a version, though we do recommend you review them for usability of your integration.
If your integration will remain private, it isn't *necessary* to pass the validation checks. You will be able to [share it with users](/platform/manage/sharing) as is. However, you can still select `Run Validation` from the *Version Overview* tab in the Platform UI or run the `zapier validate` command [in the Platform CLI](https://github.com/zapier/zapier-platform/blob/main/packages/cli/docs/cli.md#validate) to be notified of any issues and recommendations to better the user experience.
To help better address a check in communication, each check is given a unique ID, consisting of a capital letter and three digits, such as `D001`.
You don't need to know the implication of the initial capitial letter. But if you're curious, they are:
| Area | Description |
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Connected **A**ccounts | Connected accounts that are linked to your integration. We verify these to ensure the authentication is working. |
| **C**ompatibility | Only apply when your integration is public, these checks verify how the new version is backward compatible with the currently public version. They ask questions like “would this change break existing Zaps, Zap Templates, or connected accounts?” |
| **D**efinition | Definition of the integration, including auth and trigger/search/action configurations. Some of these checks could block you from saving/pushing if the violation results in a broken trigger/search/action. |
| **E**nvironment Variables | Integration environment variables may impact the runtime behavior of your integration versions. These checks may prompt you for confirmation before performing actions like migrating or promoting. |
| **L**ifecycle | The lifecycle state of your integration or its versions, such as the visibility (private, pending, or public) and the version state (deprecated, non-production, or production). |
| **M**arketing | Public-facing information, such as the app title, description, and logo. The intent of these rules is to give Zapier users a consistent style among texts and images across all public integrations. They're more likely to block you from going public. |
| **S**tats | Usage stats, such as the number of users your integration has. These are more likely to block you from going public. |
| **T** - Zap History | Data from runs in your Zap History, produced by live (enabled) Zaps. These are more likely to block you from going public. The “T” checks are named as such for historical reasons. Zapier now shows tasks in the Zap History. |
| **U**ser | Things in the developer's (your) account, such as Terms of Service acceptance. |
| **Z**ap | Things related to Zaps, such as the trigger samples you pulled into the Zap editor. |
When the checks are run, we'll give a brief blurb summarizing the violation (with a check ID) along with a link to this page. This will act as a full reference explaining each error and giving examples for each.
***
## A001 - A Connected Account Exists
To ensure you've tested auth, we require you to set up at least one connected
account.
***
## C001 - Try To Avoid Hiding/Removing Public Triggers/Searches/Creates
During promotion, we compare features of your currently public version with your soon-to-be-public version.
When you hide/remove a trigger in a new version, Zap Templates that use that trigger become invalid. Try to avoid this when you can. The same applies for searches and creates.
***
## C002 - Try To Avoid Removing Input Fields
During promotion, we compare features of your currently public version with your soon-to-be-public version.
When you change/remove the `key` property of an `input_field`, Zap Templates that use that field become invalid. Try to avoid this when you can.
***
## C003 - Try To Avoid Removing Sample Data
During promotion, we compare features of your currently public version with your soon-to-be-public version.
When you change/remove the `key` property of an item in your `sample`, Zap Templates that use that field become invalid. Try to avoid this when you can.
***
## D001 - Input Fields Should Be Insensitive
Input fields collect user-provided values. They must not contain sensitive
credentials such as API keys, tokens, secrets, or passwords.
Sensitive values should be centrally used in auth because input fields typically
aren't treated with the same level of security as auth fields are (e.g. scrubbed
from logs) and aren't action specific. Additionally, the ability to test the
validity of auth doesn't exist for action fields, so anything auth related should
be put into an auth field instead.
***
## D002 - Provide Link in Help Text for Auth Fields
It's often not obvious where a user can find their API credentials for a service. If
you use a pasted API key as an authentication method, it's strongly encouraged that
you link the user to the page (or relevant help doc) that has their key.
an example of an **incorrect** implementation:
```
API key is found on the "API Details" page in settings
```
an example of a **correct** implementation:
```
Go to the [API Details](https://my.site.com/manage/api-details) screen from your
Website Dashboard to find your API Key.
```
***
## D003 - Connection Label Should Be Valid
A Connection Label helps a customer remember which account they connected.
It should be short and easily identifiable, and must not contain sensitive
credentials such as API keys, tokens, secrets, or passwords.
For both [Platform UI](https://platform.zapier.com/build/connection-label)
and [CLI](https://platform.zapier.com/reference/cli-docs#connection-label), the
connection label is a string. You can use any data returned by your test
function, but you should never use sensitive fields.
For instance, if a successful run of the auth test returns the following data:
```js
{
"name": "Malcom Reynolds",
"email": "youcanttaketheskyfromme@serenity.com",
"job": "Captain"
}
```
Your connection label could be the following:
```
{{name}} - {{email}}
```
The most important role of the label is to uniquely identify the connection.
examples of **incorrect** connection labels:
```
"Slack"
"api_key"
"My token is: 12345"
"{{token}}"
"{{api_key}}"
"{{password}}"
"user token"
```
examples of **correct** connection labels:
```
{{user}} @ {{team}}
{{name}} - {{email}}
{{username}}
{{user}} ({{email}})
```
***
## D004 - ID Fields Should Have Dynamic Dropdowns
We've found that instead of instructing users to paste an item `id` into Zapier,
providing them with a [dynamic dropdown](https://platform.zapier.com/reference/cli-docs#dynamic-dropdowns)
greatly increases the likelihood of the user setting up Zaps correctly. Users will
still be able to map custom fields, but this gets them started on the right foot.
Read more about implementing dynamic dropdowns below:
* [Platform UI](https://platform.zapier.com/build/add-fields#dynamic-dropdown)
* [Platform CLI](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#dynamic-dropdowns)
***
## D005 - Dynamic Dropdown Connects to a Non-Existing Trigger
[Dynamic dropdowns](https://platform.zapier.com/reference/cli-docs#dynamic-dropdowns)
allow you to connect an input field to an existing trigger. The dropdown won't work
if the trigger key you specify doesn't exist.
***
## D006 - REST Hook Trigger Needs a Polling URL
When users are setting up a hook-based (aka instant) Trigger, it's important to have
a polling fallback. For example, imagine a Zap that triggers on a new Slack message.
If testing relies on the sending of a webhook, the test won't complete without the user
sending an actual message in a Slack channel, which is disruptive.
Instead, during testing, the Perform List (`performList`) operation fetches a
(real) recent message using the provided URL for polling and uses it as the test result.
The polling URL in a REST Hook trigger is only used for testing during a Zap setup.
It's very important that the structure of an object from a webhook and from a poll
are identical. Typically, this means modifying a poll result so that it looks like a
hook. If a poll has fields that a hook doesn't, the user may map them to a later
step, and when the Zap runs live, the value will be blank. This can cause errors
or unexpected results for users.
Let's walk through an example. Say we have a `New Contact` REST Hook trigger. When a
new contact is created, Zapier gets a webhook that looks like this:
```js
{
"id": 1,
"firstName": "Bruce",
"lastName": "Wayne",
"job": "Batman"
}
```
The accompanying polling URL would look something like `https://site.com/contacts/list`
and return:
```js
{
"results": [
{
"id": 1,
"firstName": "Bruce",
"lastName": "Wayne",
"job": "Batman",
"friends": [2, 3, 4]
},
{
"id": 2,
"firstName": "Alfred",
"lastName": "Pennyworth",
"job": "Butler",
"friends": [1, 3]
}
]
}
```
To match the polling result to the hook result, you would modify this response to
remove the `friends` information, and return only the array of contacts, not the
enclosing object.
The polling result is not used when a user skips testing the Zap step. In that case,
Zapier uses the sample data.
See [Sample Data](/platform/build/sample-data) for more details on
this.
***
## D007 - All URLs Should Be HTTPS
When handling customer data (which all Zapier functions do), it's strongly
encouraged that all communication take place securely. Using SSL is a big part of
that, so ensure your URLs have HTTPS as their protocol.
If you need help setting up an SSL certificate for your API, we suggest
[Let's Encrypt](https://letsencrypt.org/).
an example of an **incorrect** setup:
```text
http://example.com/messages/subscribe
```
an example of a **correct** implementation:
```text
https://example.com/messages/subscribe
```
***
## D008 - Invalid Markdown Link
A valid markdown link consists of a pair of square brackets with the link text
paired with a pair of parentheses that have the link itself. See the
[markdown cheatsheet](https://www.markdownguide.org/basic-syntax/#links) for
more info.
If you want to show a full link without actually linking to it, use backticks. This
makes it clear to the user that they don't need to click the link, it's just used as
an example. Any link used in plain text needs to either be a proper link or in
backticks.
examples of an **incorrect** implementation:
```
See [Google(https://google.com)
```
```
See https://google.com
```
examples of a **correct** implementation:
```
See [Google](https://google.com)
```
```
See `https://google.com`
```
If you see this error, you should look through both the description for the
trigger/action/search and the help text for any fields that might have bad links.
***
## D009 - Requires at Least One Search Field
When making a search step, it's important to have a field to search by. Common
examples for searching for a user are by name, email, and username.
***
## D010 - Missing Primary Key Fields in Static Sample Data
For polling triggers, the deduper uses the primary key field(s) to decide if it's
seen an object before. You can define one or more output fields as the primary key.
Each field can be a string or a number. But it's important that the primary key is
unique. If no fields are set as `primary`, the deduper will by default use the `id`
field as the primary key.
Hooks are not deduped, so they're not required to have a primary key.
This check ensures the static samples in your integration definition contain the
primary key fields. It's similar to `T002`. The difference is that `T002` validates
the live polling results in the Zap History.
an example of an **incorrect** implementation:
```js
{
// The deduper uses `id` field by default if no output fields are `primary`.
// So this sample should have an `id` field for it to pass.
"sample": {
"contact_id": 4,
"contact_name": "David"
}
}
```
```js
{
// `contact_id` is set as `primary`, but it's missing in the sample
"sample": {
"id": 4,
"contact_name": "David"
},
"outputFields": [
{ "key": "contact_id", "primary": true },
{ "key": "contact_name" }
]
}
```
examples of a **correct** implementation:
```js
{
"sample": {
"id": 4,
"contact_name": "David"
}
}
```
```js
{
// This example defines `contact_id` as the unique primary key.
"sample": {
"contact_id": 4,
"contact_name": "David"
},
"outputFields": [
{ "key": "contact_id", "primary": true },
{ "key": "contact_name" }
]
}
```
```js
{
// If multiple fields are unique together, you can set them as `primary`.
"sample": {
"repo": "zapier/zapier-platform",
"number": 1234,
"title": "Add this feature please"
},
"outputFields": [
{ "key": "repo", "primary": true },
{ "key": "number", "primary": true },
{ "key": "title" }
]
}
```
***
## D011 - Redundant Help Text
Help text is optional and meant to provide non-obvious information or links for the
user. If the label and help text are the same, they are considered redundant.
an example of an **incorrect** implementation:
```js
{
"label": "Subdomain",
"help_text": "subdomain"
}
```
an example of a **correct** implementation:
```js
{
"label": "Subdomain",
"help_text": "Where you (and your users) can access your forms, e.g., https://.typeform.com"
}
```
***
## D012 - Static Sample Is Required
When a user sets up a trigger or action (create or search), they need sample data to
be returned in order to have fields available to map in the subsequent steps. If
testing the trigger returns no live results, we use static sample data as a
fallback.
It's very important that the data structure of the response from the actual
trigger/action request and in the sample data are identical. Otherwise, users could
map fields that don't exist in the live results, which results in a broken Zap.
See [Sample Data](https://platform.zapier.com/build/sample-data) for more details on this.
***
## D013 - Connects to a Non-Existing Search
[Search-Powered Fields](https://platform.zapier.com/reference/cli-docs#search-powered-fields)
prompt users to set up a search step to populate the value of the field. It won't
work if the search key you specify doesn't exist.
***
## D014 - Has a Search Connector, but No Dynamic Dropdown
By design, to get the "Add a Search Step" button to appear for users in the Zap
editor, an action needs both a search connector and a (valid) dynamic dropdown. If
you can't provide a valid dropdown, you can instead point to a dummy trigger that
always returns an empty array.
an example of an **incorrect** setup:
```js
{
"key": "update_thing",
"search": "thing.id"
}
```
an example of a **correct** implementation:
```js
{
"key": "update_thing",
"search": "thing.id",
"dynamic": "things.id.name"
}
```
***
## D015 - Search-Or-Create Connects to a Non-Existing Action/Search
The search or create key you specify in `searchOrCreates` must reference to an
existing search or action. Otherwise, it won't work.
***
## D016 - Consists Only a Static Webhook
A REST Hook trigger missing a Subscribe or Unsubscribe endpoint, is presented to
users as a [Static Webhook](https://cdn.zappy.app/3b35908a6a0c232087b5da807cf9d6fb.png).
Static hooks are [not supported in public integrations](https://platform.zapier.com/publish/integration-checks-reference#D017),
but they could be used if the integration intends to remain private. However, Zapier
doesn't allow integrations that are a single static hook with the availability of
[Webhooks by Zapier](https://zapier.com/apps/webhook/integrations). To fix this, add
more triggers/searches/actions.
***
## D017 - Static Hook Is Discouraged
When a REST Hook trigger is missing a Subscribe or Unsubscribe endpoint, it is
presented to users as a [Static Webhook](https://cdn.zappy.app/3b35908a6a0c232087b5da807cf9d6fb.png).
As static webhooks require manual intervention by the user to set up correctly, we
no longer support adding new static webhook triggers to a public integration. Please
set up Subscribe and Unsubscribe requests for this trigger, or use a Polling trigger
type instead.
***
## D018 - Titlecased Label
In order to have a consistent style across trigger/action/search labels, they're
required to be presented in title case. If you fail this check, a passing version of
your label will be shown.
an example of an **incorrect** implementation:
```
new contact
```
an example of a **correct** implementation:
```
New Contact
```
***
## D021 - Trigger Description Requirements
Trigger descriptions must start with `Triggers when ` and end with a `.`.
examples of an **incorrect** implementation:
```
Whenever there's a new contact, this goes?
```
```
Triggers whenever there's a new contact.
```
examples of a **correct** implementation:
```
Triggers when there's a new contact.
```
***
## D022 - Creates Should Try to Have Static Input Fields
When making Zap Templates, it's helpful to have input fields that are common
for all users. Without any, it's hard to create templates. If possible,
add some static input fields that all users will be able to use.
***
## D023 - ISO-8601 Date/Time Format in Static Sample
To ensure Zapier can correctly parse dates and times, you should always use ISO-8601
format to represent dates or times. Timezone info should also be present if it
contains time.
This check is similiar to `T003`. This check validates the static samples in
your integration definition, while `T003` validates the live results
in the Zap History.
examples of an **incorrect** implementation:
```
01 Aug 2023
```
```
01 Aug 2023 06:50:30
```
```
2023-08-01T06:50:30
```
examples of a **correct** implementation:
```
2023-08-01
```
```
2023-08-01T06:50:30-0500
```
```
2023-09-15T09:59:59Z
```
***
## D024 - Static Sample Respects Output Field Definition
If you define output fields for a trigger/action/search, they should be consistent
with the static sample data. The specific checks are:
* "required" fields must be in the sample
* field values in the sample match their field type
an example of an **incorrect** implementation:
```
static sample: {"id": "1"}
output fields: [
{"key": "id", "type": "integer"},
{"key": "email", "type": "string", "required": true}
]
```
an example of a **correct** implementation:
```
static sample: {"id": 1, "email": "john@example.com"}
output fields: [
{"key": "id", "type": "integer"},
{"key": "email", "type": "string", "required": true}
]
```
***
## D025 - URLs Should Not Be Dangerous URIs
In order to help prevent reflective cross-site-scripting (XSS) attacks on Zapier
customers, we require that URLs inside the app definition do not match potentially
dangerous URI patterns which could be used to run malicious code.
Read more about XSS in the [OWASP Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html).
an example of an **incorrect** setup:
```text
javascript:alert('XSS');//
```
an example of a **correct** implementation:
```text
https://example.com
```
***
## D026 - Manual domain validation recommended if using "inputFormat" or domain-related authentication fields
When utilizing authentication fields which allow a user to input their own domain or subdomain,
we strongly recommend performing [manual validation](https://platform.zapier.com/build/subdomain-validation)
on the input data to ensure that it matches your expectations and filters out values which
could be used to redirect users into unexpected domains.
an example of an **incorrect** implementation:
```javascript
// No subdomain validation, trusting the user input
const response = await z.request({
url: `https://${bundle.authData.yourSubdomainField}.mydomain.com/oauth/token`,
// ...
})
```
an example of a **correct** implementation:
```javascript
// Manual validation step to ensure the subdomain matches your requirements
if (!/^[a-z0-9-]+$/.test(bundle.authData.yourSubdomainField)) {
throw new Error(
"Subdomain can only contain letters, numbers and dashes (-)."
);
}
const response = await z.request({
url: `https://${bundle.authData.yourSubdomainField}.mydomain.com/oauth/token`,
// ...
})
```
***
## E001 - Environment Variables have changed between versions
During promotion or migration, be sure to confirm that any environment variable
changes are intentional and won't cause runtime problems. Remember that changes to
environment variables in one version of an integration will not affect the environment
variables of other versions of the same integration.
***
## L001 - Version Is Deprecated
You can't promote a deprecated version.
***
## L002 - Version Was Already Submitted
You can't submit a version you've already submitted. If your integration was pushed
back and you want to resubmit for another review, you should make changes on a
**new** version and submit that.
***
## L003 - Version Is Already Production
This could happen if you're attempting to promote a version that is already in
production.
***
## L004 - Changes From Partners Are Blocked
This is necessary when Zapier team pushes changes to a partner-owned integration.
Partners would have to coordinate with Zapier team via [partners@zapier.com](mailto:partners@zapier.com)
to lift the restriction for subsequent changes from them.
***
## M001 - App Category Is Required
To correctly categorize your integration on Zapier, please choose the category that
fits best your app. You can specify a category for your integration in the
Integration Settings page.
***
## M002 - Description Is Invalid
Your app's description is a place to talk about your app, not ours! Even if we
really like your app, you're not allowed to say "Zapier" in your app's
description. We expect to see your app's name in the description followed by
"is a" to begin the description.
Additionally, it's discouraged that you talk about how this integration will "sync"
anything, as the space is supposed to be about your app itself instead of the Zapier
integration in particular.
Lastly, this section should be short and sweet. A brief description (roughly
tweet-sized) is best. Specifically, we're looking for 1 - 3 sentences or at least
40 characters and a maximum of 140 characters.
an example of an **incorrect** setup:
```
Google Translate enables Zapier users to translate text from one language into
another.
```
an example of a **correct** implementation:
```
Google Translate is a service that translates text from one language into another.
```
***
## M003 - Role Must Be Employee or Contractor
For your integration to go public, you must be employed or hired by the company who
makes the app used in the integration. Go to the Integration Settings page
to select your role.
***
## M004 - Invalid Logo
Your app's logo will be used all over the site in square containers and in various
sizes. To ensure it looks good at all sizes, the logo image must be:
* a square PNG image
* at least 256px by 256px in size
* in RGBA mode so it can have a transparent background
To resize an image or convert an image to PNG, you can use this
[tool](http://www.picresize.com/).
***
## M005 - Admin Team Member Email Domain Matches App Domain
To ensure that this integration is being submitted by the app owner we require that
one of the Admin team members listed on the project have an email address with the
same domain as your app's homepage URL (which must also be present). You can add the
homepage URL at `https://developer.zapier.com/app/APP_ID/version/APP_VERSION/settings`.
Collaborator team members with the same domain as the homepage do not meet this
requirement.
***
## M006 - Homepage URL Must Be Present
Each app must have a homepage URL. You can add the homepage
URL at `https://developer.zapier.com/app/APP_ID/version/APP_VERSION/settings`.
***
## M007 - Public Integration Already Exists
We only allow one public integration in our app directory for a given app. If a
public integration with the same title already exists, we won't approve your
submission to go public. If you're the owner of the existing public integration,
create an updated version with any edits and promote that instead of submitting a
new integration.
***
## S001 - 3 Users with a live Zap
To verify user demand, there should be at least 3 users who have a live Zap using
this integration. "Live" means the Zaps are switched on with at least one successful
[Zap run in recent history](https://help.zapier.com/hc/en-us/articles/8496291148685).
You can [invite others to test your integration](https://platform.zapier.com/manage/sharing)
before publication.
***
## S002 - One Live Zap for Each Trigger/Search/Action
To ensure any show-stopping bugs are worked out, every visible trigger/search/action
of your integration should have a live Zap that demonstrates it works. "Live" means
the Zaps are switched on with at least one successful
[Zap run in recent history](https://help.zapier.com/hc/en-us/articles/8496291148685).
You can create a [new Zapier account](https://help.zapier.com/hc/en-us/articles/8496197192461)
and [invite it to your integration](https://platform.zapier.com/manage/sharing) if
you need extra Zaps.
You can also [contact us](https://developer.zapier.com/contact) if you need a trial
extension.
***
## S003 - Live Version Count Limit
You can't have more than 25 previous or current production versions with live Zaps.
To continue, migrate users on older versions to a newer version.
***
## T001 - One Successful Zap Run for Each Trigger/Search/Action
There must be at least one successful Zap run for each visible trigger/action/search
in your app.
To ensure you have run a live test of every visible trigger/action/search, create a
Zap for each one, turn it on, and trigger a Zap run while it's on.
This check is performed using the [Zap History](https://zapier.com/app/history) for
accounts belonging to the integration admins, so build your test Zaps in these
accounts.
Learn more about the Zap History [here](https://help.zapier.com/hc/en-us/articles/8496291148685).
***
## T002 - Missing Primary Key Fields in Live Polling Results
For polling triggers, the deduper uses the primary key field(s) to decide if it's
seen an object before. You can define one or more output fields as the primary key.
Each field can be a string or a number. But it's important that the primary key is
unique. If no fields are set as `primary`, the deduper will by default use the `id`
field as the primary key.
Hooks are not deduped, so they're not required to have a primary key.
This check ensures the live polling results in the [Zap History](https://zapier.com/app/history)
contain the primary key fields. It's similar to `D010`. The difference is that
`D010` validates the static samples in your integration definition.
This check is performed using the [Zap History](https://zapier.com/app/history) for
accounts belonging to the integration admins, so build your test Zaps in these
accounts.
examples of an **incorrect** implementation:
```js
{
// The deduper uses `id` field by default if no output fields are `primary`.
// So this sample should have an `id` field for it to pass.
// Note that `` represents a polling result in Zap History,
// not an actual key in your integration definition.
"": {
"contact_id": 4,
"contact_name": "David"
}
}
```
```js
{
// `contact_id` is set as `primary`, but it's missing in the result
"": {
"id": 4,
"contact_name": "David"
},
"outputFields": [
{ "key": "contact_id", "primary": true },
{ "key": "contact_name" }
]
}
```
examples of a **correct** implementation:
```js
{
"": {
"id": 4,
"contact_name": "David"
}
}
```
```js
{
// This example defines `contact_id` as the unique primary key.
"": {
"contact_id": 4,
"contact_name": "David"
},
"outputFields": [
{ "key": "contact_id", "primary": true },
{ "key": "contact_name" }
]
}
```
```js
{
// If multiple fields are unique together, you can set them as `primary`.
"": {
"repo": "zapier/zapier-platform",
"number": 1234,
"title": "Add this feature please"
},
"outputFields": [
{ "key": "repo", "primary": true },
{ "key": "number", "primary": true },
{ "key": "title" }
]
}
```
***
## T003 - ISO-8601 Date/Time Format in Zap History
To ensure Zapier can correctly parse dates and times, you should always use ISO-8601
format to represent dates or times. Timezone info should also be present if it
contains time.
This check is similiar to `D023`. This check validates the data in the
[Zap History](https://zapier.com/app/history), while `D023` validates
the static samples in your integration definition.
This check is performed using the [Zap History](https://zapier.com/app/history) for
accounts belonging to the integration admins, so build your test Zaps in these
accounts.
examples of an **incorrect** implementation:
```
01 Aug 2023
```
```
01 Aug 2023 06:50:30
```
```
2023-08-01T06:50:30
```
examples of a **correct** implementation:
```
2023-08-01
```
```
2023-08-01T06:50:30-0500
```
```
2023-09-15T09:59:59Z
```
***
## T004 - Static Sample Contains a Subset of Keys from Live Result
Static samples provide Zapier users and partners a way to preview and map fields
for a trigger or action without actually making a request to your API. It's
important that static samples reflect the real results from these calls as seen
in the Zap History. Errors occur when a Zap uses a field from static sample that
is not provided once the Zap is running.
This check requires the static sample you define for each trigger/action/search to
contain a subset of the keys in the latest run in the [Zap History](https://zapier.com/app/history).
This check is performed using the [Zap History](https://zapier.com/app/history)
for accounts belonging to the integration admins, so build your test Zaps in
these accounts.
an example of an **incorrect** implementation:
```json
static: {"id": 1, "email": "john@example.com"}
live: {"id": 2, "name": "Alice"}
```
an example of a **correct** implementation:
```json
static: {"id": 1, "name": "John"}
live: {"id": 2, "name": "Alice", "email": "alice@example.com"}
```
See [Sample Data](https://platform.zapier.com/build/sample-data) for more details on this.
***
## T005 - Live Trigger Result Respects Output Field Definition
This check takes the latest run from the [Zap History](https://zapier.com/app/history)
and verifies whether the trigger result conforms to the output fields for the
trigger in your integration (if defined). The specific checks are:
* "required" fields must be in the trigger result
* field values in the trigger result match their field type
This check is performed using the [Zap History](https://zapier.com/app/history)
for accounts belonging to the integration admins, so build your test
Zaps in these accounts.
an example of an **incorrect** implementation:
```json
live result: {"id": "1"}
output fields: [
{"key": "id", "type": "integer"},
{"key": "email", "type": "string", "required": true}
]
```
an example of a **correct** implementation:
```json
live result: {"id": 1, "email": "john@example.com"}
output fields: [
{"key": "id", "type": "integer"},
{"key": "email", "type": "string", "required": true}
]
```
See [Sample Data](https://platform.zapier.com/build/sample-data) for more details on this.
***
## T006 - Polling Sample Contains a Subset of Keys from Live Result
For REST Hook triggers, we require you to provide a `Perform List` URL (check
`D006`) so that users can retrieve a real data sample in the Zap editor. This is
called a polling sample, and is created when you test the trigger in the Zap editor
before turning it on.
Errors occur when a Zap uses a field from the polling sample that is not
provided by the hook payload sent once the Zap is running.
To ensure this doesn't happen, this check compares the latest item in the
[Zap History](https://zapier.com/app/history) with the selected polling sample in
the corresponding Zap. For it to pass:
* There must be a Zap that is using the trigger.
* The Zap must have at least one Zap run (the most recent run will be used).
* The trigger must have been tested in the Zap editor via the Perform List method
to retrieve a polling sample.
* The polling sample should have the same data keys, or a subset of keys, compared
to those available in the Zap run data.
This check is performed using the [Zap History](https://zapier.com/app/history)
for accounts belonging to the integration admins, so build your test Zaps
in these accounts.
an example of an **incorrect** implementation:
```json
polling sample: {"id": 1, "email": "john@example.com"}
live: {"id": 2, "name": "Alice"}
```
an example of a **correct** implementation:
```json
polling sample: {"id": 1, "name": "John"}
live: {"id": 2, "name": "Alice", "email": "alice@example.com"}
```
See [Sample Data](https://platform.zapier.com/build/sample-data) for more details on this.
***
## U001 - Developer Terms of Service
You must agree to the latest Developer Terms of Service in order to proceed. Go to
[Developer Home](https://developer.zapier.com) to agree.
***
## Z001 - Polling Sample Respects Output Field Definition
For REST Hook triggers, we require you to provide a `Perform List` URL (check
`D006`) so that users can pull a live sample in the Zap editor. This is called a
polling sample.
This check takes the latest polling sample from a Zap with this trigger
and verifies that the sample conforms to the output fields for the
trigger in your integration (if defined). The specific checks are:
* "required" fields must be in the polling sample
* field values in the trigger result must match their field type
This check is performed using the Zaps in accounts belonging to the
integration admins, so build your test Zaps in these accounts.
an example of an **incorrect** implementation:
```json
polling sample: {"id": "1"}
output fields: [
{"key": "id", "type": "integer"},
{"key": "email", "type": "string", "required": true}
]
```
an example of a **correct** implementation:
```json
polling sample: {"id": 1, "email": "john@example.com"}
output fields: [
{"key": "id", "type": "integer"},
{"key": "email", "type": "string", "required": true}
]
```
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Integration publishing requirements
Source: https://docs.zapier.com/platform/publish/integration-publishing-requirements
We're excited you are creating an integration for the [Zapier Platform](https://zapier.com/developer-platform). We're here to help you understand our platform and its requirements so that you can successfully prepare your Zapier integration for publishing. Thousands of partners have built integrations on the Zapier Platform that enable our mutual users to set up Zaps as easily and quickly as possible.
When your Zapier integration meets these requirements, it will pass the review for the publishing process quickly and smoothly. The requirements help maintain quality and consistency for all integrations listed in our [App Directory](https://zapier.com/apps).
Please review these requirements carefully before submitting to ensure your integration is compliant. Integrations and their associated apps must meet all requirements to be published.
**Important**: integrations for prohibited apps will be removed from the platform. Integrations for restricted apps or that do not meet all requirements will be allowed to remain [private](/platform/quickstart/private-vs-public-integrations).
Work through each section and ask the [PublishBot](https://publishbot.zapier.app/) or write in via the [contact form](https://developer.zapier.com/contact) for any questions.
## Key considerations
* Because the Zapier Platform is always changing and improving to keep up with the needs of our customers, this is a living document.
* If you prefer your integration to be accessible to a limited group of users, or if the Zapier integration review requirements do not align with your needs, you might want to consider maintaining your integration as private. Learn more about [private vs public integrations](/platform/quickstart/private-vs-public-integrations).
* We encourage diversity on the Zapier Platform, provided your integration respects users with varying viewpoints and ensures a high-quality user experience. Any integration found to contain or exhibit behavior deemed inappropriate, discriminatory, or crossing acceptable boundaries will be rejected.
* We reserve the right to reject publishing requests or to remove users and integrations from the Zapier Platform if we believe these requirements, the [Platform Agreement](https://zapier.com/platform/tos), or our [Terms of Service](https://zapier.com/legal/terms-of-service) have not been met. This includes attempts to exploit the review process, illicitly acquire user data, or manipulate test users.
## Sections
## 1. Prohibited integrations
Integrations built for the following apps aren't permitted and will be removed from the Zapier Platform:
### 1.1 Apps from a restricted country
Apps/integrations must not be from companies in or under the control of any country against which the United States currently has sanctions, as per section 6(d)(iv) of the [Zapier Platform Agreement](https://zapier.com/developer-platform/tos).
### 1.2 Apps from a competitor
Apps/integrations must not be from companies we deem to be competing with Zapier, as per section 2(i) of the [Zapier Platform Agreement](https://zapier.com/developer-platform/tos).
### 1.3 Apps that do not meet Zapier or third-party agreements
Apps/integrations must comply with all Zapier and other third-party agreements, including but not limited to the [Zapier Platform Agreement](https://zapier.com/developer-platform/tos) and the [Zapier Terms of Service](https://zapier.com/legal/terms-of-service). Should we ask you to supply it, you must be ready to provide supporting documentation of permission from third parties.
### 1.4 Integrations that make financial transactions
Integrations must not facilitate any form of financial transaction, transfer of assets, or payment processing. This includes the transmission of ownership of any tokens or assets in the case of blockchain or cryptocurrency apps.
### 1.5 Apps that have misleading or malicious functionality
Apps/integrations must not mislead users. Do not create a Zapier integration that can be used to spam, phish, or send unsolicited messages to users. If you attempt to cheat the system (for example, by trying to trick the review process, steal user data, or fake real users) your integration will be removed from Zapier and you could be expelled from submitting any integrations in the future. False information and features, including inaccurate data or joke functionalities, such as fake phone calls or SMS are prohibited.
### 1.6 Apps that have objectionable content
Apps/integrations should not include content that is discriminatory, defamatory, offensive, mean-spirited, or insensitive with regard to gender, religion, sexual orientation, age, race, national/ethnic origin, or other targeted groups.
## 2. Restricted integrations
Integrations built for the following apps will not be published but will be allowed to remain [private](/platform/quickstart/private-vs-public-integrations):
### 2.1 Replacement integrations
The integration should not have an equivalent that has already been published in our [app directory](https://zapier.com/apps). Each published integration should represent a distinct, independent app to ensure the best experience for our mutual customers. If you're attempting to replace an existing public integration, please refer to the guide on [versions](/platform/manage/versions) and how to [plan changes](/platform/manage/planning-changes). Publishing separate integrations for the same app brand is not permitted.
### 2.2 Multiple integrations
Do not create separate integrations for functionality that share the same authentication method and interact with the same API, unless each integration is for a separate product or service (not feature) that is clearly marketed independently. Instead, consolidate the functionality into one, high-level integration.
## 3. Ownership and permissions
### 3.1 APIs
You own or have permission to use all APIs used by the integration. Details of those permissions are supplied on request.
The account owning the integration must have proper access to the associated platform and APIs, either by working for, being associated with, or being contracted by the company whose integration is in review. This is so we can reach out with questions or support issues during the review and after the integration is public. If it's not obvious to us that the owning account is associated with your integration's company (largely by email domain), we will request proof via an email from a matching domain as the platform or confirmation from someone at the company.
Scenarios in which integrations are permitted on the Zapier Platform by status, ownership, and intention:
| Private | Public | Not Allowed |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| Anyone that accepts [Zapier Terms of Service](https://zapier.com/platform/tos) can build a private integration. | Integrations by developers who work for the company owning the API or have been contracted by the API owner can go public. | Integrations by developers who are building on an API they own but for a competing product with Zapier. |
| Integrations by developers building on a private API with no intention of going public, are permitted to remain private/invite-only indefinitely. | Integrations by developers who work for or third-party developers (preferably a [trusted developer](/platform/quickstart/trusted-developers)) hired by the company owning the API and intended to go public, are permitted as private before going public. | Integrations by developers who do not own the API used in the integration or who have not been given explicit permission by the owners of the API. |
| Integrations by developers who are building on a public API they do not own, and routing traffic to their own servers. Exceptions apply when building on an approved third-party API. | | |
| Integrations by developers building on a public API they do not own and intend to share with their team (within their company or organization, family and friends, etc.) are only permitted to be private. | | |
| Integrations by developers building on a public API they do not own and intend to sell access to the integration, are only permitted to be private. | | |
| Integrations by developers building with sandbox/test/dev environments or endpoints are only permitted to be private. | | |
### 3.2 Trademarks
You own or have permission to use all trademarks used in the integration. Details of those permissions are supplied on request.
Zapier trademarks can't be used in an integration name, but they can be used in the description and partner marketing material in accordance with our [brand guidelines](https://brand.zapier.com/).
## 4. Data security and user privacy
### 4.1 Integration handles data appropriately
The integration does not facilitate or encourage end users to transmit or receive sensitive personal data in violation of the [Zapier Terms of Service](https://zapier.com/legal/terms-of-service).
### 4.2 Integration uses HTTPS
For security reasons, all API endpoints used by an integration (including authentication and login pages) must utilize HTTPS instead of HTTP.
### 4.3 Integration stores credentials securely
Do not hard code credentials such as API Keys, Client IDs, Client Secrets, etc. into your integration. Use the appropriate section in the Platform UI (e.g. Application Credentials) or use [environment variables](/platform/build/env) instead.
## 5. Quality and functionality
### 5.1 App has been publicly launched
Your app has been fully launched to the public and isn't an invite-only or “beta” app.
### 5.2 App APIs are documented
Your app's API and all other non-Zapier APIs used in the integration have clear, accurate, up-to-date, documentation covering all API endpoints. Links to this documentation are supplied in your publishing submission.
### 5.3 Integration is production-ready
The integration has been fully tested and does not have any unexpected or unhandled errors. All integration triggers, actions, and searches have been tested using Zaps in a Zapier account. Every test Zap has been turned on and has at least one successful run in the [Zap history](https://zapier.com/app/history).
Do not delete these Zaps or Zap runs. We may ask you to share your test Zaps with us when you submit your integration for review.
Use the Monitoring page in the Platform UI to check integration events and ensure the integration does not have unexpected or unhandled errors.
For more information and guidance, refer to [Integration Build Guidelines](/platform/publish/integration-build-guidelines) and [Test and monitor your integration in your Zapier account](/platform/build/test-monitoring).
### 5.4 Integration uses production APIs
The integration uses production API endpoints. Integrations using sandbox/test/dev endpoints will not be published
### 5.5 Integration requests authentication credentials appropriately
Authentication credentials are only requested from users via the [Authentication](/platform/build/auth) configuration. Integrations that request authentication credentials to be entered in other configurations, such as triggers, actions, or searches, will not be published.
### 5.6 Integration has a valid connection label
[Connection labels](/platform/build/connection-label) are optional but can help users identify which account each [app connection](https://help.zapier.com/hc/en-us/articles/8496258785421-Connect-your-app-accounts-to-Zapier) uses. Suitable values include account name, email address, and name.
Sensitive information such as API keys, secrets, and lengthy ID values are not allowed. Do not hard code values such as the application's name or words like “success”, as these are already communicated in the UI.
### 5.7 Integration uses English language
Currently, the Zapier Platform supports only English. All user-facing text, such as the name and description of your integration, trigger/action/search names, field names, output field labels, help texts, and error messages, must be in English. However, data sent to and received from your API can be in your product's native language.
### 5.8 Integration follows naming conventions
Triggers, actions, searches, and input fields should be named according to platform conventions. For more information, refer to [Trigger Copy](/platform/publish/integration-build-guidelines#trigger-design-and-copy), [Trigger input fields](/platform/publish/integration-build-guidelines#trigger-input-fields), [Action Copy](/platform/publish/integration-build-guidelines#action-design-and-copy), [Action input fields](/platform/publish/integration-build-guidelines#action-input-fields), [Search Copy](/platform/publish/integration-build-guidelines#search-design-and-copy), and [Search input fields](/platform/publish/integration-build-guidelines#search-input-fields).
## 6. Integration listing
### 6.1 Integration name is unique and matches your application's core branding
Enter your application name exactly as it appears in your core branding. Search our [app directory](https://zapier.com/apps) to make sure your integration name is not already in use.
Do not include trademark or copyright identifiers like a TM suffix or words like “app” or “integration.” Do not include your website's domain (e.g., `.ai`) or your company name unless they are always used in your core branding when referring to your app.
### 6.2 Integration description follows convention
Enter a short description of your application's core features and use cases, that leads with your app name in the form of ` is a....`. The description should not include links or mentions of Zapier or other apps, or make it appear your integration is associated with or endorsed by Zapier. Focus less on selling the application, instead, provide a clear explanation of what your application actually does.
**Examples**:
* `Trello is a team collaboration tool to organize anything on a kanban board.`, **not** `Trello is the best project management tool`.
* `Dropbox lets you store files online, sync them to all your devices, and share them easily.`, **not** `A file storage app`.
### 6.3 Integration homepage URL correctly set
Enter the URL of your application's marketing website, not the application URL or login page, etc.
## 7. Support
### 7.1 Application has a valid test account
The submission includes a valid test account created in the application. The test account allows Zapier support staff to view your app's interface for troubleshooting and assisting our shared users once an integration is published.
* The test account must be non-expiring and use this email address: [integration-testing@zapier.com](mailto:integration-testing@zapier.com).
* Zapier support staff must be able to change the account password unless the account uses “passwordless authentication,” such as OTP or “magic link.”
* Ensure all necessary features are enabled for testing Zap steps (triggers and actions). Include any required paid features and avoid trial limitations.
* Provide a demo video or detailed documentation for any complex features. Supply all account credentials required to log in and configure the account appropriately, avoiding super admin access or internal-only features.
### 7.2 Integration has a qualifying team member
Integrations must have at least one [admin team member](/platform/manage/add-team) with an email address from the application or API's top-level domain, or the company owning the API used in the integration. Add new team members to an integration by following this guide: [Invite team members to your integration](/platform/manage/add-team).
## 8. Submission process
### 8.1 Repeated submissions
Submitting multiple integrations that are essentially the same delays the Zapier process and risks rejection of all submissions. Please avoid flooding the Zapier team with consecutive submissions of the same integration during the review process. Violating this policy may result in slower review times or further penalties.
### 8.2 Approval discretion
At our discretion, we reserve the right to reject publishing requests or to remove users and integrations from the Zapier Platform if we believe these requirements, the [Platform Agreement](https://zapier.com/platform/tos), or our [Terms of Service](https://zapier.com/legal/terms-of-service) have not been met. This includes attempts to exploit the review process, illicitly acquire user data, or manipulate test users
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Integration success strategies
Source: https://docs.zapier.com/platform/publish/partner-faq
With 7,000+ public integration partners on Zapier, use these 10 tried-and-true tactics from our top partners to skyrocket your growth and earn you more [benefits from the Partner Program](https://zapier.com/developer-platform/partner-program).
* [Level up your team](#tip-1-level-up-your-team)
* [Monitor your integration insights on growth and usage](#tip-2-monitor-your-integration-insights-on-growth-and-usage)
* [Boost user adoption by seamlessly embedding Zapier](#tip-3-boost-user-adoption-by-seamlessly-embedding-zapier)
* [Share Zapier use cases in your onboarding](#tip-4-share-zapier-use-cases-in-your-onboarding)
* [Add new features to your Zapier integration](#tip-5-add-new-features-to-your-zapier-integration)
* [Power up your app marketplace with Zapier-enabled listings](#tip-6-power-up-your-app-marketplace-with-zapier-enabled-listings)
* [Suggest Zapier as an answer to common support questions](#tip-7-suggest-zapier-as-an-answer-to-common-support-questions)
* [Point empty marketplace search results to Zapier](#tip-8-point-empty-marketplace-search-results-to-zapier)
* [Surface Zapier in your website footer](#tip-9-surface-zapier-in-your-website-footer)
* [Leverage marketing automation](#tip-10-leverage-marketing-automation)
## Level up your team
Make sure your sales and support teams say “yes!” when asked about an integration. Share these bite-sized [Zapier 101 videos](https://learn.zapier.com/) to get them up-to-speed on Zapier.
## Monitor your integration insights on growth and usage
Review your integration insights on a regular cadence to guide making decisions and [inform you on the quality](/platform/manage/integration-insights) of your integration. We routinely hear from our partners that Zapier users are higher-value, sticky users. So, it's important to keep a pulse on how the integration is doing.
**Clearbit case study:** Clearbit carefully tracks the success of their users and discovered Zapier users are 20% less likely to churn. Armed with this data, their team prioritizes promotion and development strategies that encourage more of their users to try integrations.
## Boost user adoption by seamlessly embedding Zapier
Keep users engaged inside your own platform by embedding the Zapier experience in your app. Help users easily discover, build, and manage Zaps with our prebuilt, plug-and-play [Full Zapier Experience](https://platform.zapier.com/embed/full-zapier-experience), or utilize our [Partner API](https://platform.zapier.com/embed/partner-api) to create a seamless, custom solution.
**Jotform case study:** Jotform makes it easy for users to connect their forms to other apps to send form responses. Within every form builder, users have the ability to search for integrations, discover popular use cases, and build and edit Zaps all without leaving Jotform.
> **Do this yourself by:**
> * Using the [Full Zapier Experience](https://platform.zapier.com/embed/full-zapier-experience) or [Zap Templates](https://platform.zapier.com/embed/zap-templates) to embed popular Zaps in just a few minutes.
> * Or designing a custom experience like Jotform did via our [Partner API](https://platform.zapier.com/embed/partner-api).
## Share Zapier use cases in your onboarding
From tool tips to testimonials, make sure your newest customers know it's possible to connect your tool to 7,000+ other web apps via Zapier.
**Base CRM case study:** Base CRM shares a customer story in their onboarding sequence to help new users picture automation magic in their own work. The result? Stickier users right from the get-go.
> **Do this yourself by:**
> * Identifying a point in your onboarding sequence that makes sense to introduce Zapier to new users.
> * Linking to a customer story, a detailed help doc, or even display your most popular Zaps with [a simple snippet of code](https://platform.zapier.com/embed/zap-templates).
## Add new features to your Zapier integration
As your product evolves, your integration should, too. An up-to-date, bug-free integration makes automation simple for users.
**Thinkific case study:** As Thinkific's feature set grows, they improve their Zapier integration, too. By promoting these updates in blog posts and product newsletters, existing users learn how to power up their workflows and new users discover Zapier automation.
> **Do this yourself by:**
> * Making updates your users are asking for. Review feature requests by logging in to [the dashboard](https://developer.zapier.com/) with your developer credentials.
> * Creating new [Zap templates](https://developer.zapier.com/zap-templates) to inspire use cases.
> * Promoting the new Zapier features to your users in a blog post or email.
## Power up your app marketplace with Zapier-enabled listings
Chances are, your users are searching your marketplace for the apps they want to connect to. Close the loop on those high-intent searches with listings for the apps your users search for most, powered by Zapier.
**Any.do and Wufoo case studies:** Any.do uses our plug-and-play Full Zapier Experience to show off a huge library of integrations enabled by Zapier, while Wufoo powers its integration marketplace with our Partner API. This way, you're providing users and prospects the widest selection of apps to search through when they're looking for integrations to connect.
> **Do this yourself by:**
> * Leveraging the [Full Zapier Experience](https://platform.zapier.com/embed/full-zapier-experience).
> * Or utilizing [Zapier's Partner API](https://platform.zapier.com/embed/partner-api) to programmatically deploy and maintain your marketplace.
## Suggest Zapier as an answer to common support questions
What are your customers searching for help on? Our top partners think beyond a one-size-fits-all Zapier help doc. Whether it's how to export data to Google Sheets, or how to get custom alerts for new data, crafting custom Zapier tutorials helps you have answers at the ready.
**Trello case study:** Trello's team gets a lot of questions about how to import project data. [This help doc](https://help.trello.com/article/751-importing-data-into-trello) shows how easy it is to automatically import to Trello, and directs users to Zapier.
> **Do this yourself by:**
> * Asking your support and sales teams about the questions they often receive. Can Zapier solve these problems?
> * [Creating a pre-made Zap](/platform/publish/zap-templates) for a step-by-step solution to that common problem.
> * Writing a tutorial with the pre-made Zap [embedded](https://platform.zapier.com/embed/zap-templates) in your help docs so readers can build the workflow without leaving your site.
## Point empty marketplace search results to Zapier
Make sure your users aren't left empty-handed. When search results in your marketplace turn up empty, point them to Zapier (chances are, we support their favorite app).
**Help Scout case study:** Help Scout prompts users to search for the integrations they want. When a search result comes up empty, a short snippet of default text suggests Zapier.
> **Do this yourself by:**
> * Adding a search bar to your integrations directory.
> * Displaying this sentence as default text on an empty search state, “Can't find what you're looking for? See if you can integrate with it via Zapier.”
## Surface Zapier in your website footer
Help your users find what they're looking for by linking to your Zapier integration from your site footer.
**Close.io case study:** Close.io helps users discover their Zapier integration by linking to Zapier topics from their footer. This helps new users find out about Zapier and keeps Close.io as a top Zapier integration.
## Leverage marketing automation
Zero in on the users most likely to adopt automation into their everyday work. Watch for users to hit key milestones in your app, like creating a new contact or exporting data. Then, suggest automation as a natural next step.
**Autopilot case study:** Autopilot celebrates when users activate a chat feature, then suggests Zapier as a solution for automated contact management.
> **Do this yourself by:**
> * Identifying key actions your users that can be boosted with automation.
> * Using your marketing automation to message users who take that action.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Partner Program
Source: https://docs.zapier.com/platform/publish/partner-program
The [Zapier Partner Program](https://zapier.com/developer-platform/partner-program) is a program for Zapier's [8,000+ integration partners](https://zapier.com/apps). It is designed to give all public partners a clear path to success for their integrations and reward them with benefits along the way.
> **The Partner Program is only available to public integrations.**
As your integration gains more active users, and maintains a healthy health score, your integration will tier up in our Partner Program. Zapier's Partner Program consists of 4 tiers:
* Bronze
* Silver
* Gold
* Platinum
Learn more about the [benefits available in each tier](https://zapier.com/developer-platform/partner-program).
## How tiers are calculated
Your tier in the Zapier Partner Program is determined by your integration's number of active users and health score.

Your tier in the Partner Program is evaluated on a fixed quarterly basis: at the beginning of January, April, July, and October. Your health score is calculated daily in response to your engagement with open bug reports and feature requests.
If at the beginning of a quarter you don't meet all requirements of a tier, you will move down to the next tier that you do qualify for.
Zapier won't externally share your tier in the Partner Program with anyone, including other partners and Zapier users. But if you'd like to, you're welcome to share your tier in the program with your users.
### Active users
The active users metric looks at how many people are actively using your Zapier integration this quarter. Since this number accumulates over the quarter, it is normal to see a drop at the beginning of each quarter compared to the end of last quarter.
To increase usage of your Zapier integration, try out [these 10 tactics](/platform/publish/partner-faq).
### Integration health score
The integration health score is calculated by looking at:
* how many open feature requests have been reported for your integration
* how many open bug reports have been reported for your integration
* how responsive your team is to the open issues
Some feature requests and bugs impact your score more than others. For example, a feature request with 100 users voting for it will impact your health score more than a feature request with 1 vote.
Our goal for all integrations is for them to maintain a “healthy” health score. No tier of the Partner Program requires an “exceptional” health score.
To improve your health score, respond to and resolve your outstanding [feature requests and bugs](/platform/manage/user-feedback).
## View Partner Program metrics
You can view Partner Program metrics in two ways:
* **Partner newsletter**: Opt in to our [partner newsletter](https://developer.zapier.com/partner-settings/email), and we'll email you monthly updates.
* **Partner Program dashboard**: Log into the [developer platform](https://developer.zapier.com/) with your developer's credentials. In the left side bar, click **Partner Program** to view your metrics.
## How to monitor integration insights
As you launch and maintain your integration, monitor and review the insights in the dashboard on a regular cadence. Insights include data on the integration's growth and usage, such as monthly active users, retention rates, and Zap usage by triggers and actions. You can [see all the metrics tracked](/platform/manage/integration-insights) in this table, or access them for any integration you are an Admin or Collaborator on from the “Dashboard” tab of the developer platform.

You can filter most growth metrics by the last X number of days to identify trends and changes in user activity in correlation to marketing initiatives, integration changes, and product updates like [embedding Zapier](https://platform.zapier.com/embed/full-zapier-experience). Usage details for each trigger and action will show which functionalities are the most popular and being effectively utilized. You can easily and safely share access to the insights by [inviting collaborators](/platform/manage/add-team) to the integration without giving them permission to make changes to it.
If you have any questions about the Partner Program, reach out to the Partner Support team via the [contact form](https://developer.zapier.com/contact).
***
[*Need help? Tell us about your problem and we'll connect you with the right resource or contact support.*](https://developer.zapier.com/contact)
# Build your first public integration on Zapier
Source: https://docs.zapier.com/platform/publish/public-integration
This guide gives an overview of the process to publishing a public integration.
## Benefits to building a public integration
* Building a public integration on the Zapier Platform is free.
* There are no fees for publishing an integration.
* Users of your integration are responsible for their own Zapier plans and billing.
* Partners do not incur fees as a result of the usage of their integration.
* You'll get support from [Zapier's Partner Program](/platform/publish/partner-program) once your app has been successfully reviewed.
To see how your integration will show up on Zapier's website, you can browse the [app directory](https://zapier.com/apps). It's a great idea to explore similar apps to see what triggers and actions they provide for building Zapier workflows, called Zaps.
## 1. Before you start
Consider workflows your app will support, and what types of activities your users want to automate. Learn [how Zapier works](/platform/quickstart/how-zapier-works) and set up a few Zaps to get a sense of the user experience.
To design useful triggers and actions for your integration, consider how your users might need data from your app to run other parts of their business. Some of the most popular use cases for Zapier integrations include:
* Sending follow-up emails or messages
* Copying data from a bill or invoice into another system
* Updating contact records in multiple databases
* Creating or updating records in a project management tool
Learn more about [recommended integration features](/platform/quickstart/must-have-triggers-and-actions) by app category and how to design [popular app type integrations](/platform/quickstart/must-have-triggers-and-actions).
## 2. Build your integration
Building a Zapier integration means identifying the relevant APIs for your triggers and actions, and designing an intuitive experience for your users to select and map the data they need.
There are two ways to build an integration on Zapier's Platform:
* The Platform UI lets you create a Zapier integration in your browser without code using API endpoint URLs. You can set any custom options your API may need, including custom URL params, HTTP headers, and request body items.
* Zapier Platform CLI lets you build a Zapier integration in your local development environment, collaborate with version control and CI tools, and push new versions of your integration from the command line.
Both of these tools run on the same Zapier platform, so choose the one that fits your workflow the best.
Learn more about the difference between building with the [Platform UI and the CLI](/platform/quickstart/ui-vs-cli).
## 3. Test your integration
While you're building your integration, you can test your API requests within the Integration Builder. For developers building on Zapier Platform CLI, you can write unit tests that run locally, in a CI tool like [Travis](https://travis-ci.com/).
To get a sense of the user experience, it's recommended to test your integration within the Zap editor. [Create a new Zap](https://help.zapier.com/hc/en-us/articles/8496309697421) that uses your integration's triggers or actions to ensure they all work as expected. After you're done building, invite users to try your integration before making it available to a wider audience.
Learn more about testing your integration:
* [Testing using Zapier Platform UI](/platform/build/test-auth)
* [Testing using Zapier Platform CLI](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#testing)
## 4. Submit your integration for app review
After you've confirmed your integration is working as expected, you're almost ready to publish your app. To publish your integration, you need to submit your app for review by Zapier.
Before submitting your integration, review [Zapier's integration publishing requirements](/platform/publish/integration-publishing-requirements) or ask the [PublishBot](https://publishbot.zapier.app/) for a smoother app review process.
To submit your integration for app review:
1. [Log into the Platform UI](https://zapier.com/app/developer)
2. Select your **integration**.
3. In *Integration Home*, click **Publish.**
4. You'll need to complete the online form.
5. Click **Submit for Review**.
After you've submitted your integration for review, one of our developers will reach out to you in 1 week or less with any oustanding requirements. In the meantime, Zapier will update your:
* App version to **Pending**.
* App status will remain as **Private**.
## 5. Beta phase
When your integration is approved, Zapier will update your:
* App status to **Beta**.
* Integration will be added to [Zapier's app directory](https://zapier.com/apps) with a Beta tag.
Your integration will remain in beta for 90 days. Whilst in public beta, we recommend completing these tasks to improve your integration:
### Publish a support article in your help center
Publishing help documentation for your Zapier integration on your own website is an effective way to support
users and reduce friction in adoption. When users can easily find clear, step-by-step guides, they're more likely
to successfully set up and maintain their automations without needing to contact support, improving the user experience.
Consider [embedding Zap templates](https://docs.zapier.com/powered-by-zapier/integration-marketplace/low-code/zap-templates), troubleshooting tips for common API responses, and visual guides to aid users.
[Learn more about writing help documentation](https://docs.zapier.com/platform/publish/user-help)
### Create Zap templates
As soon as your app is published and in beta you can begin creating and sharing [Zap Templates](/platform/publish/zap-templates). Zap Templates are readymade integrations or Zaps with the apps and core fields pre-selected. In a few clicks, they help people discover a use case, connect apps, and turn on the Zap.
Learn more about creating [Zap templates](/platform/publish/zap-templates).
### Embed Zapier in your product or website
The best way to ensure users are able to discover your Zapier integration is to surface your integration where users are looking at it. By embedding Zapier in your product, you can create end-to-end user experience, helping your customers discover available integrations within your product without having to leave your app.
Learn more about [embedding Zapier](https://platform.zapier.com/embed/embed-benefits).
### Grow active usage
During the beta stage of your integration, it's important to actively work on growing the usage of your app. By encouraging more people to use your integration, you'll be able to gather valuable insights and feedback early on, which will help you optimize it further.
Learn more strategy [tips for a successful integration](/platform/publish/partner-faq).
### Manage bugs and feature requests
With the Zapier Issue Manager, you have the ability to conveniently address bugs and new feature requests within your preferred issue-tracking tool. Regularly reviewing and taking action on these items will greatly contribute to enhancing the overall health score of your integration.
Learn more about [Zapier Issue Manager](/platform/manage/user-feedback).
### Exit Beta early by embedding your integration
When one signup for Zapier is detected from your implementation of a [Zapier embed tool](https://platform.zapier.com/embed/embed-benefits), you'll exit Beta the next business day and unlock Partner Program benefits. The simplest option is to feature your Zap templates in a launch announcement. Additionally, you can present a dynamic gallery of the 6,000+ applications that are now compatible with your app for creating workflows.
## 6. Public phase
After 90 days in public beta, your integration will become public:
* Your app status will be updated to public, and the beta tag will be removed.
* You're added to our [Partner Program](https://zapier.com/developer-platform/partner-program), where you can earn marketing and support benefits.
Learn more about [maintaining your Zapier integration](/platform/manage/user-feedback).
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Create help documentation for your users
Source: https://docs.zapier.com/platform/publish/user-help
We encourage you to publish help documentation about using your Zapier integration on your own website. Having guides on your site gives users a seamless experience when they're already exploring your product, and allows you to tailor the documentation to your branding. While Zapier's support team will help users troubleshoot issues, having detailed help docs on your site enables users to self-serve and address common questions on their own.
## Self-hosted help documentation
Step-up your documentation game. Implementing these essential strategies and tips can ensure that your audience gets the assistance they need, seamlessly.
### Speak your user's language
* Identify your integration's target audience and tailor your help docs to their level of technical expertise
* Consider the common questions, pain points, and use cases your users might have
### Organize content effectively
* Structure your help docs in a logical manner, with categories, subcategories, and search functionality for easy navigation
* Use descriptive headings and bullet points to break down complex topics into bite-sized pieces
* Create a table of contents for quick reference
[Check Buffer's simple yet effective way of breaking down topics.](https://support.buffer.com/article/814-buffer-api-support-zapier-pinterest-and-whats-possible-for-users)
### Keep help docs clear and concise
* Use plain language and avoid technical jargon whenever possible
* Break down complex concepts into simple steps and provide examples or screenshots to illustrate key points
* Write in an active voice to keep the content engaging and easy to understand
### Leverage your user Community
* Encourage community engagement from users who have successfully resolved similar issues
* Community-contributed answers help leverage social proof. When users see that their peers have found solutions helpful, this adds authenticity and credibility to your help docs
* Highlighting real user experiences demonstrates that your documentation isn't just theoretical— bolstering users' confidence in its effectiveness.
### Anticipate user needs
* Include troubleshooting guides, FAQs, and best practices to address common issues and optimize user experience
* Link related articles together to provide a seamless learning experience
### Offer multiple formats
* Formats such as text-based articles, video tutorials, and interactive demos will help cater to different learning preferences and experiences
* Ensure that all formats are easily accessible and mobile-friendly for users on the go
[See how Notion offers a variety of tutorials and documentation in different formats.](https://www.notion.so/help)
### Empower user feedback
* Allow users to rate the helpfulness of your articles and provide comments or suggestions for improvement
* Monitor user feedback regularly and use it to prioritize updates and improvements to your help docs (and integration)
### Integrate help docs with support channels
* Integrate your help docs with your customer support channels such as live chat or ticketing systems to provide seamless assistance to users
### Measure and analyze usage
* Use analytics tools to track user engagement with your help docs, including page views, search queries, and time spent on each article
* Use this data to identify areas for improvement and optimize your help docs for a better user experience
### Embed Zapier within your help docs
* Give users the ability to easily and securely discover what they can accomplish with your integration through one of our [embed tools](https://zapier.com/partner/solutions/plug-and-play)
* Partners often publish articles detailing workflows with a Zap template for that specific workflow embedded using our [Workflow Element](https://docs.zapier.com/powered-by-zapier/integration-marketplace/low-code/zap-templates)
* [Learn more about other embed benefits](https://docs.zapier.com/powered-by-zapier/introduction)
[See how Taskade has embedded Zap templates using our Workflow Element to help users discover automation inpsiration.](https://www.taskade.com/blog/taskade-zapier-integrations/)
Remember to regularly review and refine your content to ensure it remains accurate, relevant, and helpful to your users.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Zap templates
Source: https://docs.zapier.com/platform/publish/zap-templates
Zapier empowers apps to do together what they can't on their own. With a bit of inspiration and creativity, your users can pull dozens of apps together into unique workflows to get more done with your app in far less time.
**Note:** Only public integrations can be used in Zap templates. Zap templates do not currently support private integrations.
Zap templates are ready made Zaps with the apps and core fields pre-selected, for publicly available Zapier integrations. In a few clicks, they help people discover a use case, connect apps, and turn on the Zap. Zap templates are the fastest way for your users to automate workflows.
[Zapier Agent Templates](https://docs.google.com/document/d/1FfpmGhqE2uMX25TSKpkW8d72U4-n8rjn_ow1Xa_0kM8/edit?usp=sharing) let you build AI-powered workflows that adapt to context and goals in real time. Unlike traditional Zaps, Zapier Agents can reason, make decisions, and dynamically choose the best actions across thousands of apps.
Google Drive Gmail Filter by Zapier
[**Use this workflow**](https://zapier.com/webintent/create-zap?template=192\&utm_source=partner\&utm_medium=embed\&utm_campaign=wfe_custom\&provider=\&entry-point-location=partner_embed\&referer=https%3A%2F%2Fplatform.zapier.com%2Fpublish%2Fzap-templates%3Futm_source%3Dpartner%26utm_medium%3Dembed%26utm_campaign%3Dwfe_custom%26referer%3Dhttps%253A%252F%252Fplatform.zapier.com%252Fpublish%252Fzap-templates\&referrer=https%3A%2F%2Fplatform.zapier.com%2Fpublish%2Fzap-templates%3Futm_source%3Dpartner%26utm_medium%3Dembed%26utm_campaign%3Dwfe_custom%26referer%3Dhttps%253A%252F%252Fplatform.zapier.com%252Fpublish%252Fzap-templates)
Typeform Google Sheets
[**Use this workflow**](https://zapier.com/webintent/create-zap?template=111\&utm_source=partner\&utm_medium=embed\&utm_campaign=wfe_custom\&provider=\&entry-point-location=partner_embed\&referer=https%3A%2F%2Fplatform.zapier.com%2Fpublish%2Fzap-templates%3Futm_source%3Dpartner%26utm_medium%3Dembed%26utm_campaign%3Dwfe_custom%26referer%3Dhttps%253A%252F%252Fplatform.zapier.com%252Fpublish%252Fzap-templates\&referrer=https%3A%2F%2Fplatform.zapier.com%2Fpublish%2Fzap-templates%3Futm_source%3Dpartner%26utm_medium%3Dembed%26utm_campaign%3Dwfe_custom%26referer%3Dhttps%253A%252F%252Fplatform.zapier.com%252Fpublish%252Fzap-templates)
Instagram Facebook
[**Use this workflow**](https://zapier.com/webintent/create-zap?template=162\&utm_source=partner\&utm_medium=embed\&utm_campaign=wfe_custom\&provider=\&entry-point-location=partner_embed\&referer=https%3A%2F%2Fplatform.zapier.com%2Fpublish%2Fzap-templates%3Futm_source%3Dpartner%26utm_medium%3Dembed%26utm_campaign%3Dwfe_custom%26referer%3Dhttps%253A%252F%252Fplatform.zapier.com%252Fpublish%252Fzap-templates\&referrer=https%3A%2F%2Fplatform.zapier.com%2Fpublish%2Fzap-templates%3Futm_source%3Dpartner%26utm_medium%3Dembed%26utm_campaign%3Dwfe_custom%26referer%3Dhttps%253A%252F%252Fplatform.zapier.com%252Fpublish%252Fzap-templates)
Google Calendar Trello
[**Use this workflow**](https://zapier.com/webintent/create-zap?template=1495\&utm_source=partner\&utm_medium=embed\&utm_campaign=wfe_custom\&provider=\&entry-point-location=partner_embed\&referer=https%3A%2F%2Fplatform.zapier.com%2Fpublish%2Fzap-templates%3Futm_source%3Dpartner%26utm_medium%3Dembed%26utm_campaign%3Dwfe_custom%26referer%3Dhttps%253A%252F%252Fplatform.zapier.com%252Fpublish%252Fzap-templates\&referrer=https%3A%2F%2Fplatform.zapier.com%2Fpublish%2Fzap-templates%3Futm_source%3Dpartner%26utm_medium%3Dembed%26utm_campaign%3Dwfe_custom%26referer%3Dhttps%253A%252F%252Fplatform.zapier.com%252Fpublish%252Fzap-templates)
Typeform Slack
[**Use this workflow**](https://zapier.com/webintent/create-zap?template=883\&utm_source=partner\&utm_medium=embed\&utm_campaign=wfe_custom\&provider=\&entry-point-location=partner_embed\&referer=https%3A%2F%2Fplatform.zapier.com%2Fpublish%2Fzap-templates%3Futm_source%3Dpartner%26utm_medium%3Dembed%26utm_campaign%3Dwfe_custom%26referer%3Dhttps%253A%252F%252Fplatform.zapier.com%252Fpublish%252Fzap-templates\&referrer=https%3A%2F%2Fplatform.zapier.com%2Fpublish%2Fzap-templates%3Futm_source%3Dpartner%26utm_medium%3Dembed%26utm_campaign%3Dwfe_custom%26referer%3Dhttps%253A%252F%252Fplatform.zapier.com%252Fpublish%252Fzap-templates)
They're also a great way to promote your app, as your Zap templates are featured in:
* Zapier's app directory
* Zapier's onboarding experience
* In many of Zapier's 7,000+ integration partners' apps and sites
Zap templates can also be featured inside your site and content to help your users start using Zapier integrations. The more Zap templates you create and the more users they have, the more likely they are to be featured. This helps your Zapier integration gain popularity and rise the ranks of the [Zapier Partner Program](https://zapier.com/developer-platform/partner-program). To learn more about embedding Zap templates (and other experiences) into your app or website, see our dedicated [embed](https://platform.zapier.com/embed/overview) section.
> Expected time to create a Zap Template: 10 minutes.
## How to build a Zap template
Creating Zap templates is straightforward and follows the same steps as building any other Zap. Start by selecting the app and trigger to initiate the Zap. Next, choose an action app and map the fields from the trigger app to the action. You can also add optional steps to customize your Zap further. Finally, give your Zap a clear title and description to help others quickly understand its purpose and when to use it.
To get started, go to Zapier's [Zap template creator](https://zapier.com/webintent/create-template) or from the [Zap Template dashboard](https://developer.zapier.com/zap-templates), click *Create Zap Template*.
### 1. Add a Trigger Step
Select the trigger app by selecting it from the "Top Apps" list or searching for the app by name.
> **Note:** Only Zapier integrations that have been launched publicly can be used in Zap templates. Integrations in `private` status cannot be used in a Zap template.
Choose the app's trigger from the dropdown that starts your Zap.
When creating Zap templates, you won’t be able to connect an account. Instead, the Zap template editor will use the sample data provided by the selected method (trigger/action/search). You can view the sample data available on the `Test` pane. If certain fields aren’t available, it’s because the integration developer didn’t include them in the integration’s sample data. While you can still use the method in the Zap template, you might not be able to pre-map fields for users in subsequent action step(s).
If there are input fields to customize the trigger, you may assign a default value or leave the input fields empty. Users will be able to input their own information when setting up the Zap. Once done, click Continue to proceed to the next step.
### 2. Add an Action Step
Select the action app by selecting it from the "Top Apps" list or searching for the app by name.
> **Note:** Only Zapier integrations that have been launched publicly can be used in Zap templates. Integrations in `private` status cannot be used in a Zap template.
Choose the app's action from the dropdown that you want to follow the trigger. Same as the trigger, the Zap template editor will load the sample data available for the selected action.
> **Note**: If you add a search action following the trigger, you will need to add another action step following the search. This is because Zaps cannot end with a search method (unless it's a dyanmic `find or create` action).
Now for the most crucial part of your Zap template: Where appropriate, map the output fields from the trigger to the input fields in the action. The action step will show input fields that are statically available. Dynamic input fields that populate based on the input of another field will not be available. For the best Zap template experience, add field mapping to as many input fields as possible to help users set up Zaps quickly. For example, you might map Gmail's `Attachment` field to `File` field for Google Drive, as well as `Attachments Filename` to the `File Name` field.
> **Note**: Custom fields from apps (i.e. fields added by users) will not be available. This is because the Zap template editor is not authenticated with an app account to fetch that data. When users create a Zap from your template, they'll be able to leverage dynamic and custom fields.
> **Tip**: Use [Zapier's date and time syntax](https://help.zapier.com/hc/en-us/articles/8496275717261-Insert-the-time-your-Zap-runs-into-a-field) to modify dates and times in action form fields.
Most dropdown menus are used to select folders, projects, and other user-generated data, and should be left blank by default. You can, however, select options for dropdowns for boolean yes/no fields if you're certain which option is best for all users of this Zap template.
Zap template action forms include `required` (denoted with a red asterix) and `optional` fields. When users set up your Zap template, they are required to complete `required` fields before turning on the Zap. If you know the best data to map to those fields, add them to make sure your users' Zaps include as much detail as possible.
> **Note**: Do not enter a value into an input field unless *every* user of the Zap Template would want that value included in the action.
Zapier then shows a `Test` pane, similar to what users see when setting up Zaps. You won't be able to test your action steps when building a Zap template. The `Test` pane will call this out, and default to showing a successful test.
### 3. (Optional) Add filters or additional action steps
You can choose to add another step to your Zap, or finish and save this Zap template with only two steps (trigger and 1 action step).
Most Zap templates only need two steps, with a trigger to watch for new or updated data from one app, and an action to do something with that data in another app. Sometimes, though, you need more steps for advanced workflows, including:
* [Additional create actions](https://help.zapier.com/hc/en-us/articles/8496257774221-Set-up-your-Zap-action) to add additional automations to your workflow
* [Filters](https://help.zapier.com/hc/en-us/articles/8496276332557) to watch for specific items from trigger or action step(s)
* [Search actions](https://help.zapier.com/hc/en-us/articles/8496241402253) to find specific data from apps, recommended especially to find customers, tickets, projects, and more before creating new items with Zaps
To add another search or create action to your Zap, click the `+` button where you want to insert the additional step. Then repeat step 2 and set up the additional action.
For example, you could add a filter between the trigger and action step to have the action step only run when specific criteria is met. [Learn more about filters](https://help.zapier.com/hc/en-us/articles/8496276332557-Add-conditions-to-Zaps-with-filters). You can define a filter in the Zap template, or leave it blank and let users customize the filter to their needs.
> **Note**: Most Zap templates don't need filters, and most filters should be added by users later if required. However, including a filter in a Zap template can be useful if your Zap Template is only useful with a filter to remove extraneous data.
> **Note**: Paths by Zapier, Code by Zapier, Webhooks by Zapier, Looping by Zapier, and Formatter by Zapier action steps are currently not allowed in Zap templates.
### 4. Add a title, description, and test your Zap template
Once you've finsihed building your Zap template, you can give it a title and description. Click `Submit` in the top-right corner or at the bottom of the `Test` in the last step of your Zap template.
After clikcing `Submit`, you will be prompted to provide a title and description for the Zap template.
Zap templates are designed to highlight specific use cases and inspire users to automate workflows with popular apps. A clear, compelling title grabs attention and conveys the core idea at a glance, whether users are browsing Zapier or exploring an embedded experience. The description provides more detail, explaining the use case and how the Zap works. Together, the title and description work to spark interest and guide users to quickly set up and activate the Zap.
#### How to write a Zap template title
The title clearly and briefly states the apps the Zap connects and the workflow it accomplishes. They include the trigger and action apps and the actions they perform. They use present tense, active voice, and sentence case.
Most Zap template titles read something like this: `Add new Gmail emails to Google Sheets as rows`. The title mentions what happens in the trigger app followed by what Zapier does in the action app. Some examples of good titles:
* `Create Trello cards for new Wufoo form entries`
* `Get Slack notifications for new Google Drive files in a folder`
* `Subscribe new Gumroad customers to a MailChimp list`
* `Save new liked SoundCloud tracks to Google Drive`
> **Tip**: Use your discretion whether to mention the action or trigger app first. The trigger app works best first in most cases, but sometimes it sounds awkward — if so, go with the action app first.
Follow these rules in your Zap template titles:
* **Start with an appropriate verb**. Zap templates start with an action verb that describes what the Zap does in the action app, such as `Create`, `Add`, `Make`, `Insert`, `Update`, `Subscribe`, or `Get`. Use unique verbs when possible, and use the most appropriate verb for the action Zapier performs with the app.
* **Use sentence case**. Capitalize the first letter in the title and app names when appropriate.
* **Right:** `Create Trello cards for new Wufoo form entries`
* **Wrong:** `Create Trello Cards For New Wufoo Form Entries`
* **Use present tense and active voice**. Zaps automatically run whenever the trigger conditions are met. The title should reflect that with active present tense.
* **Right:** `Get Slack notifications for new Google Drive files`
* **Wrong:** `Slack will notify you when a new Google Drive file is saved`
* **Always specify if the trigger involves *new* or *updated* items**. Zaps typically run when a new item is created, or an existing item is updated. Be sure to include *new* or *updated* in the title before mentioning the action app name to clarify what the Zap will automate..
* **Make app items plural**. Zaps run on every new or updated item in your trigger app. Always make the trigger and action items plural to emphasize that, such as `Google Sheets rows` or `Mailchimp subscribers`.
* **Respect app name styles**. Make sure to use the same capitalization and spelling that the apps in your Zap use in their branding; double-check the app's site or [Zapier's integration list](https://zapier.com/apps).
* **Never use `sync` or `automatic` in titles**. All Zaps run automatically, and can't sync data bidirectionally. Avoid these terms in titles; sync is misleading, and automatic is redundant.
* **Don't use personal pronouns**. Never use `you`, `we`, or `I` in Zap Template titles unless the trigger or action items specifically include those words.
#### How to write a Zap template description
Zap template descriptions share more detail about what the Zap does and scenarios in which to use it in two to four sentences. They tell readers what this Zap does for them and how it works.
Start your description with the user's problem or need. Then explain how Zapier meets that need, when the Zap will run, and what the Zap does when it runs. Explain the trigger and action items in plain language that show the workflow's value. Some good examples:
> Find yourself spending too much time adding event attendees to your CRM by hand? Now with the help of Zapier, the tedious work is done for you. This integration will add every new Eventbrite attendee to Zoho CRM as a new contact, saving you time for more important work.
> After someone fills out a form on your site, you'll want to hear about it or send them a follow-up email. This Zapier automation handles both gracefully, sending an email via Gmail to you or the form respondent whenever you get a new Typeform entry. You'll never have to send the same message over and over again.
> Expedient order processing makes for happy customers. Make sure you act on every new delivery with this Zapier automation. It will capture every new order placed on your Shopify store after being set up, creating a delivery task for it on Onfleet so your team can fulfill it without delay.
Keep these guidelines in mind:
* **Use present tense and active voice** as in the Zap title.
* **1 paragraph, 2-4 sentences** is enough for most Zap Template descriptions.
* **Don't use Zapier-specific terminology** including Zap, Zap template, trigger, action, or terms that Zapier doesn't support, such as sync. Instead, use generic words, such as `integration` or `automation`, that are universally understood.
* **Use same terms as the integrations themselves**. If an app calls the results of a form an “entry” don't call it a “submission,” or if an email app uses “tags,” don't refer to “folders.”
* **Don't include links**. Do not include links of any kind, whether Zapier-owned or third-party owned.
* **Include tips at the end**. If your Zap Template requires extra setup for filters or other steps, or if it doesn't cover all use cases users may expect, include a sentence at the end to clarify. Start the tip with `Note:`, and format the entire note in italics with [Markdown](https://zapier.com/blog/beginner-ultimate-guide-markdown/) formatting. For example: `*Note: Add the tag you want to the Zap's Filter step.*`
> **Note**: Always write unique descriptions for each Zap template — Zap templates that use the same descriptions but only replace app names, or those that duplicate the Zap template title, will be rejected.
***
Once you've added your Zap template title and description, click `Save Draft`.
Now try using the Zap template to make sure it works as expected. Open your [Zap Template dashboard](https://zapier.com/zap-templates/), click the `...` icon beside the Zap template you built, and select `Create Zap`. A new window will open, creating a Zap from the Zap template. Click through each step of the Zap, validate everything works as expcted, and that you can turn the Zap on.
### 5. Submit Zap template for review
When your Zap template is ready for public release, click `Submit for Review` in the same modal where you added the title and description. This will submit the Zap template to our team to review to ensure it works as expected and meets our standards.
After your Zap template(s) have been reviewed, we'll send you an automated email with the subject *We've reviewed your Zap templates!*. Reviews are typically completed within 2 weeks. If your Zap template(s) are approved, we will publish them to have them appear on your app's directory page and in our embed solutions.
If your Zap template is rejected, the automated email will provide a reason and how the Zap template needs to be updated before re-submitting for review.
You can create and submit as many Zap templates as you like! The more you create, the easier it will be for users to discover your integration and build Zaps using it.
## Manual field mapping (custom pills)
When creating a Zap template, you typically map data between steps by selecting from a list of fields (or “pills”) that have been added as sample data by the integration developer. Field mapping is what allows data to carry from one step to another. Custom pills take this a step further by letting you map fields that you know are returned by an integration, but haven't been added as sample data. For example, if you wanted to map the field `eventType` between the trigger and step 2 of your Zap template, but `eventType` isn't available in the trigger's sample data, you could create a custom pill to pull this field dynamically. Here's how to create custom pills.
**Step 1: Identify the step position**
* The trigger is in position 1, with subsequent steps numbered sequentially
**Step 2: Determine the field name**
* Because the sample data doesn't include the field you want, we suggest setting up a live Zap replicating the Zap template you want to create
* After publishing your Zap, let the Zap run live and then review its Zap history
* From the Zap history, you can identify the exact name of the field you want to pull data from
* In this example, we can see Google Calendar > New Event returns the field `eventType`
**Step 3: Combine step position and field name**
* Once you have both the step position and field name, you can combine them to create a custom pill
* Start with 2 open curly braces `{{`
* Add the step position folllowed by 2 underscores `__`
* Next, add the field name
* Finally, finish with 2 closed curly braces `}}`
Example: the `eventType` field isn't returned in the sample data for Google Calendar > New Event. If you want to map that field in a Zap template, you can do so using the custom pill `{{1__eventType}}`.
**Step 4: Insert custom pill**
* You can insert the custom pill into any field in any step that comes after the field that returns the data
**Additional Notes**
* Custom pills work in both Zap templates and regular Zaps. [Learn more about creating custom pills in Zaps](https://community.zapier.com/featured-articles-65/how-to-manually-map-fields-that-do-not-appear-in-the-sample-data-aka-custom-pill-mapping-9738).
* Custom pills will only work when a live Zap run returns the field used in the custom pill. If the field isn't returned during a live Zap run, fields where the custom pill has been mapped will remain empty
* The methodology described above only works for top-level fields. If a field is nested under another field (or multiple fields), each nest would be separated by double underscores.
* For example, if the trigger returned the following and you wanted to retrieve the response for question 3, your custom pill would look like this: `{{1__questions__3}}`
By following these steps, you should be able to effectively add custom pills to your Zap Templates.
## Promote your Zap templates
It's not enough to turn your ideal workflows into Zap templates. You need to get them in front of your end-users. Zapier automatically promotes your Zap templates in our SEO, app directory, and on partner sites using our embed tools (where both your and their apps are used in the template). You can promote Zap templates further by embedding them into your site (user dashboards, blog posts, help articles) using our [Zap template element](https://platform.zapier.com/embed/zap-templates).
### Zapier app directory
Your published Zap templates will appear on your directory page. Zap templates are loosely ordered by popularity, helping users easily discover common use-cases. Users can also search for Zap templates that connect your app with another.
## Manage your Zap templates
Over time, you'll likely make dozens of Zap templates. You can manage them — in draft, review, or publicly available — from your [Zap templates](https://zapier.com/zap-templates/) dashboard alongside Zapier's Developer Platform tools.
Filter through your Zap templates by status on the left sidebar, click a Zap template to edit it, or select the gear icon on the right of a Zap template to copy its public link, test it, or delete it.
If you have any Zap templates in your *Rejected* list, edit them to fix the issues then re-submit them. You cannot edit public Zap templates, but if you notice something that you need to change in your existing Zap Templates, please [submit our contact form](https://developer.zapier.com/contact) with the Zap template ID. We can set the Zap as *Draft* again so you can edit and re-submit it for review with any changes.
### Promoting new versions of your integration
When promoting a new version of your integration, all Zap templates using the integration and having no breaking changes with the existing version will be updated to use the promoted version. The following are considered breaking changes:
* A trigger/action is hidden or deleted
* A trigger/action key is changed
* A trigger/action input field key is changed or removed
* A trigger/action output field key is changed or removed
If breaking changes exist between the previous and newly promoted integration versions, existing Zap templates will not be automatically updated and will continue to use the previous version. This can result in an older version acquiring new users over time. Consider the user impacts of [changes made in new versions](/platform/manage/planning-changes).
### Deprecating versions of your integration
When deprecating a version of your integration, any Zap templates using the integration will automatically be marked as *Invalid* within 24 hours of the deprecation.
While invalid, the Zap template will not be *Public* until it is adjusted to use a non-deprecated version, re-submitted for review and approved. This ensures users won't use deprecated and broken Zap templates to make Zaps. If you're having trouble accessing *Invalid* templates, please [submit a ticket.](https://developer.zapier.com/contact)
## Frequently Asked Questions
When contacting support about Zap templates, you'll need to provide the Zap tempalte ID you need support with. There are multiple ways to find a Zap template's ID.
From the [Zap template dashboard](https://developer.zapier.com/zap-templates), click the `...` icon beside the Zap template.
From inside the Zap template editor, click the Zap template title at the top of the screen and click and click `Copy Template ID`.
If you try to edit a Zap template that is pending reivew or public, the Zap template ID will be shown with a message to contact support.
When view a Zap template on Zapier's website, the Zap template ID can be found in the URL.
Your integration's directory page will show all published Zap templates that use your integration. The developer platform will only show Zap templates created by the currently logged in user.
Any user on Zapier is able to create and publish Zap templates using any integration that is in beta or public status. Zapier also identifies real-world usage and automatically generates Zap templates to help users discover use cases, enhance integration usage, and create more engaged users on both platforms. All Zap templates are subject to the same review process to ensure our quality standards are met.
Currently, we do not offer the option for integrations to opt out of Zapier-generated Zap templates. These templates are designed based on real-world usage to enhance the end-user experience by highlighting commonly implemented workflows. They also aim to boost adoption for both Zapier and our integration partners.
Zap templates, once published on your integration's directory page, remain in place to ensure our ecosystem is open, inclusive, and offers a wide range of options to users. This includes showcasing integrations that might combine your services with those of competitors. While direct removal of these templates isn't aligned with our approach, we offer a proactive solution. By leveraging our [Zap Template embed tool](https://platform.zapier.com/embed/zap-templates), you have the power to highlight specific Zap templates you prefer, directly within your own platform. This empowers you to curate and showcase the integrations most relevant to your users' needs.
Once a Zap template is published, you are unable to self-serve changes to it. To request changes, please submit our [contact form](https://developer.zapier.com/contact). When submitting the contact form, please ensure you provide the Zap template ID and the change you're requesting per Zap template. Please note the following when requesting changes:
* Zap templates should work for the broadest audience. Try to avoid requesting changes that will exclude an audience segment from successfully using a Zap template
* Every partner on Zapier has their own style and tone. We will not update titles or descriptions of Zap templates created by other partners to better accommodate your preferences. While a title and description might not match your tone and style, it could very well for the partner that published the Zap template
* If you believe you found an error with a title or description (eg the title references the wrong action), we will review and consider making the correction
* When requesting a functional change to a Zap template created by another partner, clearly state the Zap templates current behavior and the expected behavior to justify the requested change
Our current sorting system prioritizes Zap templates based on popularity and user engagement, ensuring users who land on your integration's page on Zapier see the most helpful examples of real workflows. The sort order cannot be modified.
All published Zap templates that use your integration will appear on your directory page. You are unable to exclude published Zap templates from appearing on that page. Note when embedding Zap templates using the [Zap Template Element](https://platform.zapier.com/embed/zap-templates), you can specify which Zap templates to embed.
You cannot view Zap templates in the developer platform created by other users, even if you're on the same integration team. If required, we can help to transfer ownership of Zap templates created by your integration team members to a singular account. You can [submit our contact form](https://developer.zapier.com/contact) to learn more about this.
Zap templates are a key driver of traffic for your integration. Promoting Zap templates is a part of our SEO strategy, and they appear throughout our embed network. For these reasons, we err against unpublishing Zap templates where possible. For Zap templates you own, you can unpublishing them by [deleting them](/images/c0f9036c4b6f166b4c8289034558c201.webp). If you wish to unpublish a Zap template without deleting it, you can request this by submitting our [contact form](https://developer.zapier.com/contact). Be sure to include the Zap template ID. When requesting to unpublish a Zap template created by another partner, please justify the request (eg duplicate Zap template, Zap template broken) for our consideration.
Zap templates can be rejected due to different reasons. The day after your Zap templates are rejected, you'll receive an email notification that will include feedback as to why a Zap template might have been rejected. Some common reasons for why Zap templates are rejected include:
* The title and/or description of the Zap template does not comply with our [style guide's](/platform/publish/zap-templates#4-add-a-title-and-description) uniqueness requirements
* Fields in the trigger step have not been correctly mapped to corresponding fields in the action step(s)
* The use case for the Zap template is considered too narrow or specific for general use
* A Zap template with a similar use case already exists
* The Zap template title and/or description was written in a language other than English
* The Zap template includes a code, custom webhook, or custom formatter step which is currently not allowed
* The Zap template contains hardcoded values such as phone numbers, emails, or IDs which should be dynamically mapped from the trigger or another action step
* Submitting a large number of Zap templates for an integration with a low active user count can lead to rejection. We aim to ensure that our review resources are allocated fairly across all partners. When a disproportionate amount of submissions comes from a single source, it negatively impacts the review process for others. To maintain a balanced and efficient review process, we enforce limits based on the size and usage of the app
Yes, but only through our [Zap Templates](https://platform.zapier.com/embed/zap-templates) embed solution. You can choose between Popular Zap templates or Specific Zap templates, to highlight to your users.
Although we don't provide specific data around how many users are using a particular Zap template, you can track the number of active Zaps as well as activation rates by Trigger or Action. This information is available within your developer dashboard on the Dashboard page. You can learn more about the insights avilable on the Dashboard page [here](/platform/manage/integration-insights). Zap templates are also loosely ordered by popularity on your integration's directory page.
The more the merrier! One Zap template isn't enough—you'll want to make Zap templates for each of your app's most popular use cases. Although there's not a set number, we recommend adding 5 to 10 Zap templates to your integration, for a start. Learn more about Building Zap templates [here](/platform/publish/zap-templates#how-to-build-a-zap-template).
Common reasons your Zap template stopped working include breaking changes, versioning, migration, and authentication. Adding, updating, replacing, or deleting components can have various effects. Learn more about [planning and implementing integration changes](/platform/manage/planning-changes).
Your triggers, actions, and searches should focus on the main use cases of your platform. Check similar integrations in [Zapier's App Directory](https://zapier.com/apps) and [recommended features](/platform/quickstart/must-have-triggers-and-actions) by app category for ideas on which items to include in your integration.
Yes. Most Zap templates only need a trigger and two action steps. However, we know sometimes you may need more steps for advanced workflows. Learn more [here](/platform/publish/zap-templates#3-optional-add-filters-or-additional-action-steps).
All users requires their own Zapier account in order to create Zaps, even if the Zap originates from a Zap template. The account the Zap is owned by will add and store authentications for each app used in the Zap. To help reduce friction for new users, you should pair your embed solution with our [Quick Account Creation](https://platform.zapier.com/embed/quick-account-creation). This seamless, accelerated sign-up feature allows first-time Zapier users to skip the standard sign-up procedure and onboarding survey.
***
*Need help?* [Tell us about your problem](https://developer.zapier.com/contact) *and we'll connect you with the right resource.*
# Zapier Partner Sandbox
Source: https://docs.zapier.com/platform/publish/zps
Zapier Partner Sandbox is a workspace for people in your organization who are on your integration team.
## What is Zapier Partner Sandbox?
It offers qualifying partners several premium features for free. Zapier Partner Sandbox is designed to support the ongoing development of your integration. Features of Zapier Partner Sandbox include:
* Unlimited Zaps
* 2,000 free tasks per month
* Actions for specific Zapier apps do not count towards task usage per our standard [task usage policy](https://help.zapier.com/hc/en-us/articles/8496196837261-How-is-task-usage-measured-in-Zapier#h_01HKCHCC1X6535JW9WPWV2TV9Y)
* 5-minute update time for polling Zaps
* Multi-step Zaps
* 5 Premium Integrations
* Paths (3 paths wide by 3 paths deep)
Zapier Partner Sandbox **does not** include any other premium features not listed above (eg static IP, pay-per-task billing). Zapier Partner Sandbox does not include premium features for Zapier Tables or Zapier Interfaces.
## Who is eligible for Zapier Partner Sandbox?
Each Admin or Collaborator on a public integration team can request access to Zapier Partner Sandbox.
## How to apply for Zapier Partner Sandbox
Visit the “Manage Team” page in the developer platform for your qualifying integration, and submit the form linked at the top of the page.
## How to access Zapier Partner Sandbox
When your request is approved, you'll continue to log into Zapier using your existing account. Clicking the icon in the top-right corner (1) will allow you to switch between your personal Zapier account (2) and the Zapier Partner Sandbox workspace (3). Your personal account will show the name set on your profile, while the Zapier Partner Sandbox workspace will show a “ZPS” avatar and “App XXX”, where “XXX” is replaced by your app ID.
Zaps created in the Zapier Partner Sandbox workspace will have access to premium features. Your personal Zapier account will remain unchanged.
## FAQ
Zapier Partner Sandbox is solely to be used for:
* Integration Development. The ongoing development of your integration.
* Sales Enablement/Demonstrations. Demonstrations of specific illustrative workflows that highlight the capabilities and benefits of your integration with Zapier. These demonstrations can be used as part of sales presentations or marketing materials to your prospective clients.
If you require a Zapier plan for commercial purposes beyond what's stated above, you're required to upgrade your personal account to one of our [in-market plans](https://zapier.com/pricing). We reserve the right to revoke your access to Zapier Partner Sandbox if we suspect you are using the account for commercial purposes.
Write into [partners@zapier.com](mailto:partners@zapier.com) and we'll be happy to assist!
Currently, we are not issuing credits instead of access to Zapier Partner Sandbox.
Qualifying users can request access by submitting the form linked at the top of the “Manage Team” page in the developer platform for their qualifying integration. You can also manually add other integration team members to your Zapier Partner Sandbox workspace. When manually adding users, they will receive an email requiring them to accept the Zapier Partner Sandbox Terms of Use. If the Terms of Use are not agreed to within 7 days, their access will be removed. If ineligible members are added to your Zapier Partner Sandbox (ie users that are not an Admin or Collaborator for your integration), their access will be removed within 1 business day.
Your access to Zapier Partner Sandbox can be revoked under the following circumstances:
* If your integration reverts to private
* If you are removed from the integration team
* If we suspect Zapier Partner Sandbox is being used for commercial purposes, we reserve the right to revoke your access to Zapier Partner Sandbox
Zapier reserves the right to modify, suspend, or discontinue this benefit at any time, with or without notice to you
No, Zapier Partner Sandbox is a benefit exclusively for partners with a public integration.
Zapier Partner Sandbox workspaces are owned and maintained by Zapier. These workspaces are created on a per-integration basis.
Yes. [Learn more about moving Zaps between accounts](https://help.zapier.com/hc/en-us/articles/8496275081357-Move-Zaps-between-accounts).
No, once your access to Zapier Partner Sandbox is removed, transferring Zaps to your personal account is impossible.
Yes, you can request access to Zapier Partner Sandbox for each qualifying integration. Visit the “Manage Team” page in the developer platform for each of your qualifying integrations, and submit the form linked at the top of the page.
Yes. Visit the “Members” page for the Zapier Partner Sandbox account from the [settings page](https://zapier.com/app/settings/).
The email address shown is the systematic owner of your integration's Zapier Partner Sandbox workspace. This is owned and maintained by Zapier. You are unable to log into Zapier using that account.
No, Zaps and folders you create in Zapier Partner Sandbox are only accessible to the user that created them.
Zapier's standard task usage policies apply to Zapier Partner Sandbox. You can [learn more about what counts as a task](https://help.zapier.com/hc/en-us/articles/8496196837261-How-is-usage-measured-in-Zapier).
No, the 2,000/month task limit applies to the Zapier Partner Sandbox workspace, not per user. Note that if you have access to multiple Zapier Partner Sandbox workspaces, each has its own task limit.
Currently, Zapier Partner Sandbox does not support metered billing.
If you exceed the task allowance, you will need to wait for the task usage to reset at the start of the next billing cycle. When viewing the Zapier Partner Sandbox workspace, you can see how many days remain until the usage resets in the bottom-left corner.
## Terms of Use
Zapier Partner Sandbox is a benefit of our Developer Program which Zapier may, in its sole discretion, choose to make available to select partners. Because Zapier Partner Sandbox may be made available to you at no additional charge, you must agree to the following in order to use Zapier Partner Sandbox:
1. Your use of Zapier Partner Sandbox is subject to Zapier's [Terms of Use](https://zapier.com/legal/website-terms-of-use)
2. Zapier Partner Sandbox is a discretionary benefit intended to support (together, the “Purpose”): A. Integration Development. The ongoing development of your integration. B. Sales Enablement/Demonstrations. Demonstrations of specific illustrative workflows that highlight the capabilities and benefits of your integration with Zapier. These demonstrations can be used as part of sales presentations or marketing materials to your prospective clients, but as mentioned below in (6), production data should not be run through any such workflows.
3. Zapier Partner Sandbox may only be used for the Purpose and not for any other purposes, including other commercial ones. If you need to use Zapier outside of the Purpose, including as a customer to create/develop automation workflows in support of your business (other than the demonstration ones referenced above), you must upgrade your personal account to a currently offered plan, which you may view at: [http://zapier.com/pricing](http://zapier.com/pricing).
4. The Zapier Partner Sandbox workspace is owned and operated by Zapier, with access granted exclusively to qualifying users.
5. In the event that Zapier determines that an account is being used outside of the Purpose, Zapier reserves all rights, including being able to revoke access to Zapier Partner Sandbox.
6. Because Zapier Partner Sandbox may only be used for the Purpose, and the Zapier Partner Sandbox workspace is owned and operated by Zapier, you agree not to submit any production data through Zaps created within the Zapier Partner Sandbox workspace. You further agree that for program management purposes, the Zapier Partnerships team has access to Zaps created within the Zapier Partner Sandbox workspace and that you should not have the expectation of privacy that you would with a Zapier customer account.
7. Zapier Partner Sandbox is provided on an “as-is” basis. Zapier reserves the right to modify, suspend, or discontinue this benefit at any time, with or without notice to you. Zapier may also update these Zapier Partner Sandbox terms at any time, and you can always find the most current version in our platform documentation.
8. The provisions of Section 3(e) (Beta Release) are incorporated by reference. In particular, Zapier is not and will not be liable for any Zaps or data that run through the Zapier Partner Sandbox workspace. Users acknowledge and assume full responsibility for their Zaps and any associated data stored in the Zapier Partner Sandbox workspace.
9. Zapier Partner Sandbox permits you to invite other users to the workspace. You may invite members of your integration team to the workspace (who will be asked to agree to these terms as well in order to maintain their access), but please do not add anyone who is not a member of your integration team. Zapier will be auditing membership in the workspace and any non-integration team members will be removed at Zapier's discretion.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# App Developer Services
Source: https://docs.zapier.com/platform/quickstart/app-developer-services
If you don't have the time or resources to dedicate towards developing your own integration, Zapier has Solution Partners who may be able to assist you. Solution Partners can build and maintain Zapier integrations for you, including private integrations, public integrations, and custom actions, making them a smart way to extend your dev team’s capacity.
## Featured Solution Partners
If you're looking for additional Solution Partners or help with Zap workflows, contact one of our [Solution Partners](https://zapier.com/partnerdirectory/) who can help you out.
**Note:**
*Solution Partners are third parties and not Zapier. When working with a Solution Partner on integration development, ensure you have a plan for long-term support and maintenance, whether through the original Solution Partner or a dedicated in-house team.*
*Need help?* [Tell us about your problem](https://developer.zapier.com/contact) *and we'll connect you with the right resource or contact support.*
# Build your integration on Zapier
Source: https://docs.zapier.com/platform/quickstart/build-integration
This guide will walk you through what steps you need to take to build an integration from start to finish. There are no fees to build an integration with Zapier.
You can choose to build with either [Zapier Platform UI or Zapier Platform CLI](/platform/quickstart/ui-vs-cli).
## 1. Prerequisites
* The app you wish to integrate will need to have a [publicly-accessible API](https://zapier.com/learn/apis/)
* Create a [Zapier account](https://zapier.com/sign-up)
* If you haven't used Zapier before, learn the basics in our [Zapier Getting Started Guide](https://zapier.com/learn/zapier-quick-start-guide/)
## 2. Choose a developer tool
Select [one of the two ways](/platform/quickstart/ui-vs-cli) to build an integration on Zapier's Platform.
* The Platform UI lets you create a Zapier integration in your browser without code using API endpoint URLs. You can set any custom options your API may need, including custom URL params, HTTP headers, and request body items.
* Zapier Platform CLI lets you build a Zapier integration in your local development environment, collaborate with version control and CI tools, and push new versions of your integration from the command line.
Both of these tools run on the same Zapier platform, so choose the one that fits your workflow the best. You can try both methods out with the [Platform UI tutorial](/platform/quickstart/ui-tutorial) and the [Platform CLI tutorial](/platform/quickstart/cli-tutorial).
## 3. Create a new integration
Create and add details about your integration. Set your Intended audience.
* [Create an integration using Zapier Platform UI](https://developer.zapier.com/app/new)
* [Create an integration using Zapier Platform CLI](/platform/build-cli/overview#creating-a-local-integration)
## 3. Add an authentication scheme
Configuring authentication allows users to input credentials to authenticate with your API.
* [Authentication using Zapier Platform UI](/platform/build/auth)
* [Authentication using Zapier Platform CLI](/platform/build-cli/overview#authentication)
* [Authentication schema](https://github.com/zapier/zapier-platform/blob/main/packages/schema/docs/build/schema.md#authenticationschema)
## 4. Configure triggers
Triggers are how your app's users can start automated workflows whenever an item is added or updated in your app. Use webhook subscriptions or polling API endpoints to create triggers.
* [Configure a trigger using Zapier Platform UI](/platform/build/trigger)
* [Configure a trigger using Zapier Platform CLI](/platform/build-cli/overview#triggers-searches-creates)
* [Trigger schema](https://github.com/zapier/zapier-platform/blob/main/packages/schema/docs/build/schema.md#triggerschema)
## 5. Configure actions
Actions allow users to either create, search or update records in your app via your API.
* [Create an action using Zapier Platform UI](/platform/build/action)
* [Create an action using Zapier Platform CLI](/platform/build-cli/overview#triggers-searches-creates)
* [Search schema](https://github.com/zapier/zapier-platform/blob/main/packages/schema/docs/build/schema.md#searchschema)
* [Create schema](https://github.com/zapier/zapier-platform/blob/main/packages/schema/docs/build/schema.md#createschema)
## 6. Test your integration
While you're building your integration, you can test your API requests within the Platform UI. For developers building on Zapier Platform CLI, you can write unit tests that run locally, in a CI tool like [Travis](https://travis-ci.com/).
To get a sense of the user experience, it's recommended to test your integration within the Zap editor. [Create a new Zap](https://help.zapier.com/hc/en-us/articles/8496309697421) that uses your integration's triggers or actions to ensure they all work as expected. After you're done building, invite users to try your integration before making it available to a wider audience.
Learn more about testing your integration:
* [Testing using Zapier Platform UI](/platform/build/test-auth)
* [Testing using Zapier Platform CLI](/platform/build-cli/overview#testing)
## 7. Validate your integration
Run automated checks to identify errors and recommendations on how to improve the user experience of your private integration. These checks are required to pass for public integrations, and are recommended for a better user experience for private integrations.
* [Run automated checks using Zapier Platform UI](/platform/publish/integration-checks-reference)
* [Run automated checks using Zapier Platform CLI](https://github.com/zapier/zapier-platform/blob/main/packages/cli/docs/cli.md#validate)
## 8. Invite team members
You can assign different roles and permissions to team members who you're collaborating with on your private integration.
* [Invite team members using Zapier Platform UI](/platform/manage/add-team)
* [Invite team members using Zapier Platform CLI](https://github.com/zapier/zapier-platform/blob/main/packages/cli/docs/cli.md#teamadd)
## 9. Publish
Once you've built your integration, Publish it!
* [Share your integration](/platform/manage/sharing)
## 10. Conclusion
Once you've built your integration, continue to make further improvements and manage versions of your integration.
* [Manage integration versions using Zapier Platform UI](/platform/manage/versions#managing-versions-in-platform-ui)
* [Manage integration versions using Zapier Platform CLI](/platform/manage/versions#managing-versions-in-platform-cli)
**Tip**: Learn from the Zapier team and other [Zapier Platform developers in
our community forum](https://community.zapier.com/p/developer-zone).
# Platform CLI tutorial
Source: https://docs.zapier.com/platform/quickstart/cli-tutorial
This tutorial walks you through the process of building, testing, and pushing an example app to Zapier using Platform CLI. We'll use a mock API for recipes in this tutorial, but for production Zapier apps, you'd want to connect to a real API.
## Prerequisites
* You'll need a [Zapier account](https://zapier.com/sign-up).
* Your dev environment meets the [requirements for running Platform CLI](/platform/build-cli/overview#requirements) with the proper version of Node.js installed.
* Install the Platform CLI tool
```bash
# Install the CLI globally
npm install -g zapier-platform-cli
```
To see a list of all the available commands in Platform CLI, try `zapier help`.
* Next you'll need to identify yourself via the CLI.
```bash
# Setup auth to Zapier's platform with a deploy key
zapier login
```
Zapier writes your deploy key to `~/.zapierrc`. You'll want to keep that file safe and not check it into source control.
## 1. Start an integration
Use the `init` command to setup the [needed structure](https://github.com/zapier/zapier-platform/tree/main/example-apps). You'll be presented with a list of available templates to start with.
```bash
# Create a directory with the minimum required files and choose a template
zapier init example-app --template minimal
# Move into the new directory
cd example-app
```
Inside the directory, you'll see a few files. `package.json` is a typical requirements file of any Node.js application. It's pre-populated with a few dependencies, most notably the `zapier-platform-core`, which is what makes your app work with the Zapier Platform. There is also an `index.js` file and a test directory (more on those later). Before we go any further, we need to install the dependencies for our app:
```bash
npm install
```
### `index.js`
`index.js` is the entry point to your app. This is where the Platform will look to understand how your app will interact with Zapier. Open the app directory you created in your code editor of choice.
You may see the following in `index.js`:
* a single `module.exports` definition which will be interpreted by Zapier
* `triggers` will describe ways to trigger off of data in your app
* `searches` will describe ways to find data in your app
* `creates` will describe ways to create data in your app
* `resources` are purely optional but convenient ways to describe CRUD-like objects in your app (see [an example resources app](https://github.com/zapier/zapier-platform/tree/main/example-apps/resource))
* `beforeRequest` & `afterResponse` are hooks into the HTTP client to manipulate the request/response on every call
## 2. Add a trigger
Add a [**trigger**](/platform/build-cli/overview#triggers-searches-creates) configured to read data from a mock API:
```bash
zapier scaffold trigger recipe
```
The [scaffold](https://github.com/zapier/zapier-platform/blob/main/packages/cli/docs/cli.md#scaffold) creates a new file `recipe.js` in the `triggers` folder. When building your own integration, you'll likely name your JS files with nouns like `contact.js`, `lead.js` or `order.js`.
Open `triggers/recipe.js` (file created by `zapier scaffold trigger recipe`) and **replace** it with:
```js
const listRecipes = async (z, bundle) => {
const response = await z.request(
"http://57b20fb546b57d1100a3c405.mockapi.io/api/recipes"
);
return response.data;
};
module.exports = {
key: "recipe",
noun: "Recipe",
display: {
label: "New Recipe",
description: "Triggers when a new recipe is created.",
},
operation: {
perform: listRecipes,
sample: {
id: 1,
createdAt: 1472069465,
name: "Best Spaghetti Ever",
authorId: 1,
directions: "1. Boil Noodles\n2.Serve with sauce",
style: "italian",
},
},
};
```
To try out the trigger locally, try running `zapier invoke`. The command will ask you which action you'd like to invoke. Now we only have one trigger `recipe`, so you can choose that one.
```
$ zapier invoke
? Which action type would you like to invoke? trigger
? Which "trigger" key would you like to invoke? recipe
✔ Invoking triggers.recipe.operation.inputFields
✔ Invoking triggers.recipe.operation.perform
[
{
"id": "1",
"createdAt": 1471984289,
"name": "name 1",
"authorId": 63,
"directions": "directions 1",
"style": "style 1"
},
]
```
Let's review the code. The function definition for `listRecipes` handles the API work, making the HTTP request and returning the parsed response data.
In JavaScript, `async/await` are syntactic sugar built on top of [Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). Be sure to use `await` or `.then()` when you call asynchronous functions.
The `listRecipes` function receives two arguments, a `z` object and a `bundle` object.
* The [Z Object](/platform/build-cli/core#z-object) is a collection of utilities needed when working with APIs. In our snippet, we use `z.request` to make the HTTP call.
* The [Bundle Object](/platform/build-cli/core#bundle-object) contains any data needed to make API calls, like authentication credentials or data for a POST body. In our snippet the Bundle is not used, since we don't require any of those to make our simple GET request.
It is possible to accomplish the same tasks using alternate Node.js libraries, but it is preferable to use the `z` object as there are features built into these utilities that augment the Zapier experience like logging of HTTP calls and error handling.
In `module.exports`, we export some metadata plus our `listRecipes` function and a sample. We'll explain later how Zapier uses this metadata and exposes it to the end user. For now, know that it satisfies the minimum info required to define a trigger.
As well as defining the trigger, the `scaffold` command has done the following:
`index.js` file now includes:
```bash
const getRecipe = require('./triggers/recipe')
```
```js
module.exports = {
// ...
triggers: {
[getRecipe.key]: getRecipe,
},
// ...
};
```
In test/triggers folder, the `recipe.test.js` file was created:
```js
const App = require("../../index");
const appTester = zapier.createAppTester(App);
// read the `.env` file into the environment, if available
zapier.tools.env.inject();
describe("triggers.recipe", () => {
it("should run", async () => {
const bundle = { inputData: {} };
const results = await appTester(
App.triggers.recipe.operation.perform,
bundle
);
expect(results).toBeDefined();
// TODO: add more assertions
});
});
```
You should be able to run the test with `zapier test` and see it pass:
```bash
$ zapier test
Validating project locally
No structural errors found during validation routine.
This project is structurally sound!
✔ Running integration checks ... 23 checks passed
Integration checks passed, no issues found.
Adding /Users/marinahand/.zapierrc to environment as ZAPIER_DEPLOY_KEY...
Running test suite with the following command:
npm run --silent test --
PASS test/triggers/recipe.test.js
PASS test/triggers.test.js (7.52 s)
Test Suites: 2 passed, 2 total
Tests: 3 passed, 3 total
Snapshots: 0 total
Time: 9.429 s
Ran all test suites.
```
For this example, we'll stick to a single test, but you can see what multiple tests look like in [another of the example apps](https://github.com/zapier/zapier-platform/blob/main/example-apps/trigger/test/triggers.js).
## 3. Modify a trigger
To let users tweak the cuisine style of recipes they are triggering on, you can provide an input field a user can fill out.
In `triggers/recipe.js`, **replace** the file with:
```js
const listRecipes = async (z, bundle) => {
const params = {};
if (bundle.inputData.style) {
params.style = bundle.inputData.style;
}
const requestOptions = {
url: "http://57b20fb546b57d1100a3c405.mockapi.io/api/recipes",
params: params,
};
const response = await z.request(requestOptions);
return response.data;
};
module.exports = {
key: "recipe",
noun: "Recipe",
display: {
label: "New Recipe",
description: "Triggers when a new recipe is created.",
},
operation: {
inputFields: [
{
key: "style",
type: "string",
helpText: "Which styles of cuisine this should trigger on.",
required: false,
},
],
perform: listRecipes,
sample: {
id: 1,
createdAt: 1472069465,
name: "Best Spagetti Ever",
authorId: 1,
directions: "1. Boil Noodles\n2.Serve with sauce",
style: "italian",
},
outputFields: [
{ key: "id", label: "ID" },
{ key: "createdAt", label: "Created At" },
{ key: "name", label: "Name" },
{ key: "directions", label: "Directions" },
{ key: "authorId", label: "Author ID" },
{ key: "style", label: "Style" },
],
},
};
```
See how the input field key `"style"` was added in the following places:
* In the `inputFields` on `operation` - this defines the field as exposed in the Zap Editor for the user to see. The field is not required, so it could be null.
* In the `listRecipes` function - we use the provided style via the bundle `bundle.inputData.style`.
Since you are developing locally, rerun `zapier invoke` to verify everything still works. This time, let's skip those interactive prompts. Specify the action type (`trigger`), the key (`recipe`), and the input data in the command, and you'll see:
```
$ zapier invoke trigger recipe --inputData '{"style":"style 20"}'
✔ Invoking triggers.recipe.operation.inputFields
✔ Invoking triggers.recipe.operation.perform
[
{
"id": "20",
"createdAt": 1578590011,
"name": "name 20",
"authorId": 90,
"directions": "directions 20",
"style": "style 20"
}
]
```
Let's also tweak the test. In test/trigger, replace the `recipe.test.js` file with:
```js
const zapier = require("zapier-platform-core");
const App = require("../../index");
const appTester = zapier.createAppTester(App);
describe("triggers", () => {
describe("new recipe trigger", () => {
it("should load recipes", async () => {
const bundle = {
inputData: {
style: "style 2",
},
};
const results = await appTester(
App.triggers.recipe.operation.perform,
bundle
);
expect(results.length).toBeGreaterThan(1);
const firstRecipe = results[0];
expect(firstRecipe.name).toEqual("name 2");
expect(firstRecipe.directions).toEqual("directions 2");
});
it("should load recipes without filters", async () => {
const bundle = {};
const results = await appTester(
App.triggers.recipe.operation.perform,
bundle
);
expect(results.length).toBeGreaterThan(1);
const firstRecipe = results[0];
expect(firstRecipe.name).toEqual("name 1");
expect(firstRecipe.directions).toEqual("directions 1");
});
});
});
```
You can run your test again and make sure everything still works:
```js
zapier test
```
## 4. Deploy an integration
To take your local app integration and make it available to use in a Zap, you'll need to push it to Zapier.
You can have many versions of an app, which simplifies making breaking changes and testing in the future. For now, you will push a single version.
Since this is your first time pushing your app version, you'll need to register your app with Zapier. Run the `zapier register` command and Zapier will ask you to provide a name and some details about your app. Follow the prompt and then you can push your app using `zapier push`:
Zapier will ask you to provide a name and some details about your app with the `zapier register` command. Follow the prompts and then push your app again.
```
$ zapier push
✔ Copying project to temp directory
✔ Installing project dependencies
✔ Applying entry point file
✔ Building app definition.json
✔ Validating project schema and style
✔ Zipping project and dependencies
✔ Testing build
✔ Cleaning up temp directory
✔ Uploading version 1.0.0
Push complete! Built build/build.zip and build/source.zip and uploaded them to Zapier.
```
Log in and visit the [Zap editor](https://zapier.com/app/editor) to create a Zap with your new integration.
For the trigger step, choose your app and the "New Recipe" trigger, where you can see the label and description that were defined in `triggers/recipe.js`.
In the Zap editor, see the input field `"style"` and fill it out. Run the trigger test and the `listRecipes` function associated with the trigger runs, making the API request and returning the result to Zapier.
Go back to your terminal. Use the `zapier logs --type http` command to see the HTTP requests Zapier made.
```
$ zapier logs --type http
The logs of your app "Example App" listed below.
┌────────┬────────┬────────────────────────────────────────────────────────┬───────────────┬─────────┬──────────────────────────────────────┬───────────────────────────┐
│ Status │ Method │ URL │ Querystring │ Version │ Step │ Timestamp │
├────────┼────────┼────────────────────────────────────────────────────────┼───────────────┼─────────┼──────────────────────────────────────┼───────────────────────────┤
│ 200 │ GET │ http://57b20fb546b57d1100a3c405.mockapi.io/api/recipes │ style=italian │ 1.0.0 │ a9055e16-fc0d-4fb2-a3e6-9d442d1f70e8 │ 2016-09-13T15:11:30-05:00 │
└────────┴────────┴────────────────────────────────────────────────────────┴───────────────┴─────────┴──────────────────────────────────────┴───────────────────────────┘
Most recent logs near the bottom.
```
## 5. Add authentication
Authentication is crucial to interacting with most APIs. Zapier supports a number of different [authentication schemes](/platform/build-cli/overview#authentication). In this example, you are going to set it up to include an API Key in a header.
For different types of authentication, see these example apps:
Define the `authentication` section for the example app you've built. In `index.js`, **add** the following to `module.exports`:
```js
authentication: {
type: 'custom',
fields: [{ key: 'apiKey', type: 'string' }],
test: async (z, bundle) => {
const response = await z.request('http://57b20fb546b57d1100a3c405.mockapi.io/api/me');
return response.data;
},
},
```
The above snippet defines the two required properties of `authentication`:
* `fields` is where we define our auth fields. This works similar to the `inputFields` of triggers. When users connect their account to Zapier, they'll be prompted to fill in this field, and the value they enter becomes available in the `bundle.authData`. Not every authentication type will include `inputFields`.
* `test` is a function used during the account connection process to verify that the user entered valid credentials. The goal of the function is to make an authenticated API request whose response indicates if the credentials are correct. A profile in the connected app, such as a `/me` endpoint, is a common choice. If valid, the test function can return anything. On invalid credentials, the test needs to raise an error. Since `z.request()` already throws an error for non-2xx responses, we don't need to throw an error explicitly in this case.
Next, make sure the API key is included in all the requests your app makes.
In `index.js`, **edit** the file to include:
```js
// Add this helper function above `module.exports`:
const addApiKeyToHeader = (request, z, bundle) => {
request.headers["My-Auth-Header"] = bundle.authData.apiKey;
return request;
};
// module.exports = ...
```
The helper function `addApiKeyToHeader`, adds the user-provided API key as a request header called `My-Auth-Header`. The name chosen is illustrative, the header would be whatever the API you are integrating with requires. Sometimes, an API would require it in a query parameter instead of a header, and/or encoded first. You'll want to reference the API documentation for the expected format.
Finally, to ensure the helper function takes effect, it needs to be registered in the app.
In `index.js`, **edit** `module.exports` to also include:
```js
beforeRequest: [
addApiKeyToHeader, // new line of code
],
```
`beforeRequest` is a list of functions that are called before every HTTP request that uses `z.request`. It's where you add headers, query params, or whatever is needed to be within *all outbound requests*. With this addition, every outgoing HTTP request made by `z.request` will now have the API key added in a header.
The `zapier invoke` command has `auth test` subcommand that essentially calls the `authentication.test` function for you to verify the credentials locally. But first, you need to initialize the auth credentials with the `auth start` subcommand:
```
$ zapier invoke auth start
The .env file does not exist or is empty. You may need to set some environment variables in there if your code uses process.env.
? apiKey | string: mock-api-key
Auth data appended to .env file. Run `zapier invoke auth test` to test it.
```
Next, run the `auth test` subcommand to verify the credentials. You'll know you have the right API key if you can see the response data from the `/me` endpoint:
To check progress, re-push the app.
```
$ zapier invoke auth test
✔ Invoking authentication.test
[
{
"id": "1",
"createdAt": 1473801403,
"userName": "userName 1"
}
]
```
Re-push the app to Zapier to deploy the changes:
```bash
zapier push
```
Go back to your Zap at [https://zapier.com/app/zaps](https://zapier.com/app/zaps). It will now have a new ["Account" item](https://cdn.zappy.app/9096a3bc1d6cd8147fb695bb460692b2.png) in your "New Recipe" trigger.
Add an account by entering any value you like for the API key, the mock API does not care.
As soon as you add the account, Zapier will run your app's `authentication.test` function to confirm the credentials are valid.
We can verify the header is present in the request by looking at the logs again.
```
$ zapier logs --type http --detailed --limit=1
The logs of your app "Example App" listed below.
┌─────────────────────┬────────────────────────────────────────────────────────────────────────────────────────┐
│ Status │ 200 │
│ Method │ GET │
│ URL │ http://57b20fb546b57d1100a3c405.mockapi.io/api/me │
│ Querystring │ │
│ Version │ 1.0.0 │
│ Step │ │
│ Timestamp │ 2016-09-16T15:57:51-05:00 │
│ Request Headers │ user-agent: Zapier │
│ │ My-Auth-Header: :censored:6:b1af149262: │
│ Request Body │ │
│ Response Headers │ server: Cowboy │
│ │ connection: close │
│ │ x-powered-by: Express │
│ │ access-control-allow-origin: * │
│ │ access-control-allow-methods: GET,PUT,POST,DELETE,OPTIONS │
│ │ access-control-allow-headers: X-Requested-With,Content-Type,Cache-Control,access_token │
│ │ content-type: application/json │
│ │ content-length: 59 │
│ │ etag: "-80491811" │
│ │ vary: Accept-Encoding │
│ │ date: Fri, 16 Sep 2016 20:57:51 GMT │
│ │ via: 1.1 vegur │
│ Response Body │ [{"id":"1","createdAt":1473801403,"userName":"userName 1"}] │
└─────────────────────┴────────────────────────────────────────────────────────────────────────────────────────┘
```
You can see from the detailed log that the request included our auth header. The value appears as `:censored:6:b1af149262:`, which is intentional. Zapier does not log authentication credentials in plain text.
## 6. Invite team members to help manage your integration
Share your integration with your team of fellow developers so it shows up in their [developer dashboard](https://developer.zapier.com/).
From the Zapier CLI, run either of these:
* `zapier team:add user@example.com admin` to invite a team member [as an admin](https://platform.zapier.com/manage/add-team) for the app.
* `zapier team:add user@example.com collaborator` to invite a team member [as a collaborator](https://platform.zapier.com/manage/add-team) for the app.
Replace the example email address with the user you want to invite.
## 7. Share users to your integration
Once you have at least one trigger or action, you'll want to share your integration with some of your users. Early feedback helps make sure you're building functionality that will be used.
From the Zapier CLI, run `zapier users:add user@example.com 1.0.0` to email this user to let them view and use the app version 1.0.0 in their Zaps.
Replace the example email address with the user you want to invite. You'll see a confirmation prompt, type `Y`.
The alternative way to invite anyone to use your app in their Zaps is via a link to the app. Run `zapier users:links` to see a public sharing link per specific version or a link to all versions. The link looks something like `https://zapier.com/platform/public-invite/1/222dcd03aed943a8676dc80e2427a40d/`. You can put this in your help docs, post it to your website, add it to your email campaign, etc. Access shared via these links cannot be revoked once shared with your users.
## 8. Modify your integration
If you need to make any changes to your integration in [a new version](/platform/build-cli/overview#deploying-an-integration-version). Versions helps to track and manage changes to your integration over time.
Public integrations or private integrations with more than 5 users **require** a new version to make any edits. It is still recommended to make changes for private integrations with fewer than 5 users in a new version as well and [consider Zapier's best practices](/platform/manage/planning-changes) when doing so.
Integrations created with the Platform CLI cannot be edited in the Platform UI. You can't add triggers or actions, edit code or configurations - these options will be grayed out in the UI.
The following details of your CLI integration can be managed from the UI if preferred:
* Invite team members
* Monitor integration usage
* Submit your integration to be made publicly available
* Promote a new integration version to public
* Migrate users between versions
## Learn more
* [Z object](/platform/build-cli/core#z-object)
* [Bundle object](/platform/build-cli/core#bundle-object) for functionalities available within the `perform` functions
* [Different authentication schemes and search/create implementations examples](https://github.com/zapier/zapier-platform/tree/main/example-apps)
* [Interactive tutorial](https://developer.zapier.com/cli-guide/introduction) that uses the GitHub API (a little outdated)
* About [different types of support](/platform/quickstart/get-help) available to help you build your integration
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Get help with the Zapier Platform
Source: https://docs.zapier.com/platform/quickstart/get-help
Get help building your app integration through the following channels:
## Developer Support on the Zapier Platform
The Platform Support team is equipped to assist you with a variety of topics to ensure your development process is as smooth as possible. Here's how we can help:
* **Integration Maintenance & Launch**: Guidance on updating your integrations and launching new versions through both our UI and CLI.
* **Authentication, Trigger & Action Setup**: Assistance with configuring authentication to your API and configuring the triggers and actions that make your integrations run.
* **Error Handling**: Advice on best practices for error messaging and handling, aiming for clarity and helpfulness to end-users.
* **Log Troubleshooting**: Support in interpreting and troubleshooting logs to resolve issues swiftly.
The following areas are however beyond our support scope:
* **Custom JavaScript Code**: We cannot provide support for writing or structuring your custom JavaScript code.
* **API Behavior Debugging**: We're unable to offer assistance with debugging unpredictable behaviors from third-party APIs.
* **Application-Specific Advice**: While we'd love to help with everything, we can't provide tailored suggestions for the specifics of your individual application.
We encourage developers to use our comprehensive documentation and community resources for topics that fall outside of our support boundaries. Our aim is to empower you with the tools and knowledge you need to excel on the Zapier Platform.
Reach out to our Platform Support team via the [contact form](https://developer.zapier.com/contact).
## Partnering with Zapier
For public integrations, the Partner Support team is here to help with:
* **Integration Launch**: We're here to guide you with launching your integration in the [Zapier App Directory](https://zapier.com/apps).
* **The Partner Program**: Any questions about [the program](https://zapier.com/platform/partner-program) and help redeeming perks.
* **Branding and Page Updates**: Updating your integration's branding and directory page.
* **Solutions for Embedding**: Any questions about [embedding Zapier](https://platform.zapier.com/embed/overview) in your app and Zap templates.
Reach out to our Partner Support team via the [contact form](https://developer.zapier.com/contact).
## Build Faster with Zapier Solution Partners
If you're working to build [public](/platform/quickstart/private-vs-public-integrations#public-integrations) or [private](/platform/quickstart/private-vs-public-integrations#private-integrations) integrations on the Zapier Developer Platform but need additional technical expertise or your developers are focused on other priorities, consider partnering with a Zapier Solution Partner. Our certified Zapier Solution Partners can help you build integrations quickly and efficiently, ensuring your projects stay on track. Whether you need guidance building an integration or full end-to-end integration development, a Zapier Solution Partner can provide the expertise and assistance you need.
Learn more about Zapier Solution Partners who are [trusted integration developers](/platform/quickstart/trusted-developers), or [search the Zapier Solution Partner Directory](https://zapier.com/partnerdirectory).
## Zapier's Developer Community
Zapier's Platform [community](https://community.zapier.com/p/developer-zone) is dedicated to helping developers with new and existing integrations. With a worldwide team of users, there's usually someone around to answer your questions. We'd love to hear about your experience building on Zapier.
## Zapier Support
If you have issues with a Zap or your Zapier account, reach out to Zapier Customer Support via the [contact form](https://zapier.com/app/contact-us). This lets the support team access technical information in your account to troubleshoot your problem. You'll receive an email response from a member of the support team regarding your issue.
## Zapier Help Center
[Zapier's Help Center](https://zapier.com/help) is a robust library of documents and step-by-step guides that explain how Zapier works, provide information about the apps you use on Zapier, and offer solutions for common issues that you may run into.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Zapier Glossary
Source: https://docs.zapier.com/platform/quickstart/glossary
* **Zapier**: An integration platform that connects over 7,000+ web apps and APIs together into [multi-step, automated, customizable workflows](/platform/quickstart/how-zapier-works). When an event happens in one app, Zapier can tell another app to perform (or do) a particular action.
* **Zap**: An [automated Zapier workflow](https://help.zapier.com/hc/en-us/articles/8496309697421) that connects your app to others that have built integrations. Each Zap consists of a trigger and one or more actions. When you turn your Zap on, it will run the action steps every time the trigger event occurs.
* **Trigger**: The app integration event that [starts a Zap when new or updated data is added](/platform/build/trigger) to your app, either by Zapier polling a specific API endpoint to check for new data or via a notification REST webhook from your app that pushes new data to Zapier.
* **Action**: The app integration step that [finds, creates, or updates data](/platform/build/action) in your app using a GET, PUT or POST request to your API using data provided when a Zap is triggered by an event in another app.
* **Create action**: The app integration step that creates or updates a single item in your app through an API call.
* **Search action**: The app integration step that finds existing data in your app, optionally with a create action to add an item if the search does not return a result.
* **Task**: An action that a Zap successfully completes will count towards [task usage](https://help.zapier.com/hc/en-us/articles/8496196837261). The number of tasks a user has depends on their [Zapier pricing plan](https://zapier.com/pricing).
* **Zap editor**: The [user interface](https://zapier.com/editor) where end users build their Zaps, adding triggers and actions built by app integration developers.
* **Zap history**: An end user's [log of all the Zaps](https://help.zapier.com/hc/en-us/articles/8496291148685#h_01HD2KKYMTS7ASSEPXRMT57H63) that have run live, showing the data going in and out of each step, any error messages and task usage.
* **Filter**: A built-in Zapier function that users can add to their Zap to [restrict it to run](https://help.zapier.com/hc/en-us/articles/8496276332557) only when certain conditional values contain specific data.
* **Paths**: A built-in Zapier function that users can add to their Zap to combine Filters and Actions to perform different actions based on different conditions. [Paths use conditional, if/then logic](https://help.zapier.com/hc/en-us/articles/8496288555917): if A happens in your trigger app, then perform this action, if B happens, then perform this other action.
* **Formatter**: A built-in Zapier function users can add to their Zap to [customize and manipulate](https://zapier.com/apps/formatter/help) text, number and date data that is output from triggers and actions.
* **Delay**: A built-in Zapier function users can add to their Zap to [place it on hold](https://help.zapier.com/hc/en-us/articles/8496288754829-Add-delays-to-Zaps) for a specified amount of time before the remaining actions run, in essence scheduling the action.
* **Input Fields**: [Individual data fields](https://help.zapier.com/hc/en-us/articles/8496259603341-Different-field-types-in-Zaps) are received from trigger and action steps in a Zap, and mapped into subsequent steps' by a user to send that data as inputs to those steps' destination API.
* **Beta**: If your app is published in the Zapier App Directory, it will [remain in Beta](/platform/publish/public-integration#5-beta-phase) for 90 days to indicate its newer status to end users.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# How Zapier works
Source: https://docs.zapier.com/platform/quickstart/how-zapier-works
[Zapier is a tool](https://zapier.com/how-it-works) that helps you automate repetitive tasks between two or more apps, no code necessary. Our customers use Zapier to move information from one app to another automatically rather than manually. Each Zap you create starts with a trigger (something that happens in one app) and then one or more actions (something else that happens in another app).
In order to connect your app to the 7,000+ apps on the Zaper Platform to allow your users to build Zaps, your app will need to have a publicly-accessible API which you can use to build your Zapier integration.
For an intro to APIs in general, check out the [guide](https://zapier.com/learn/apis/).
When you're ready to get started, [the UI tutorial](/platform/quickstart/ui-tutorial) offers a great introduction to building your first Zapier integration.
## What do Zapier integrations include?
Zapier integrations are comprised of three core concepts: Authentication, Triggers and Actions.
Authentication connects an app to Zapier. Users authenticate their account with an app to allow Zapier to access their data in that app. Once a user authenticates, Zapier will use the same authentication credentials for every API call the integration makes on the user's behalf.
Triggers are how your app's users can start Zaps (automated workflows) whenever an item is added or updated in your app.
Actions are how your app's users can create new or update existing items in your app.
## How does building an integration work?
All new Zapier integrations are built using Zapier Platform v3, the latest version of our developer platform. You can build integrations using Zapier Platform UI, an online visual builder to create integrations in a form layout. Or, you can use Zapier Platform CLI, a command line interface to build integrations in JavaScript code from your local development environment.
Both interfaces use the same Zapier Platform and function the same internally, with some [differences to consider when building](/platform/quickstart/ui-vs-cli).
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Private vs public integrations
Source: https://docs.zapier.com/platform/quickstart/private-vs-public-integrations
When building an integration on the Zapier Platform, you must specify the intended audience.
The intended audience determines whether the integration will be private or public:
* Public integration: For access to all Zapier customers and published in the [Zapier App Directory](https://zapier.com/apps).
* Private integration: For personal, internal (e.g. with your team) or controlled-access use.
* Building a private or public integration on the Zapier Platform is free.
* There are no fees for sharing or publishing an integration.
* Users of your integration are responsible for their own Zapier plans and billing.
* Partners do not incur fees as a result of the usage of their integration.
Both private and public integrations can connect to Zapier's app directory of over [7,000+ integrations](https://zapier.com/apps). Depending on your intended audience, there will be different features available and limitations to what the integration can do.
> **Note**: The intended audience is different from your integration's status. All integrations, regardless of intent, start with a private status. Learn more in [Zapier integration publishing requirements](/platform/publish/integration-publishing-requirements).
## Public integrations
Public integrations are suitable for the following use cases:
* Connect your app product to Zapier for public use.
* Gain exposure from Zapier's 3 million+ users.
By creating a public integration, you'll have access to these features:
* Join the [Zapier Partner Program](https://zapier.com/platform/partner-program).
* Publish your integration in [Zapier's app directory](https://zapier.com/apps).
* [Create Zap templates](/platform/publish/zap-templates).
* [Embed Zapier in your product](https://platform.zapier.com/embed/overview).
* [Embed Zap Templates in your product](https://platform.zapier.com/embed/zap-templates).
* Use [Zapier Issue Manager](/platform/manage/user-feedback#3-consider-zapier-issue-manager) to manage bugs and feature requests.
* Users of your integration can [share a template of their Zaps](https://help.zapier.com/hc/en-us/articles/8496292155405-Share-a-copy-of-your-Zap).
* Users of your integration can use [Zapier's ChatGPT plugin](https://help.zapier.com/hc/en-us/articles/14058263394573).
### Limitations
If you're building a public integration, there are specific limitations to be aware of:
* To create a public integration, you need to meet the [Integration Ownership criteria](/platform/publish/integration-publishing-requirements#21-integration-ownership).
* You can have up to [100 admins and collaborators](/platform/manage/add-team).
* You can't restrict who uses your public integration.
## Private integrations
Private integrations are suitable for the following use cases:
* Connect your internal tool or system to Zapier.
* Connect your app product to Zapier to exclusively allow your team to build workflows.
* Create an integration for a staging or testing environment.
**Note**: We strongly recommend against the use of an independent private integration for staging purposes in the case of an existing public integration. Instead, use a private [version](/platform/manage/versions) for this purpose.
By creating a private integration:
* You control who has access to your integration.
* Your private integration won't appear within [Zapier's app directory](https://zapier.com/apps).
### Limitations
If you're building a private integration, there are specific limitations to be aware of:
* Rate limits depend on the Zapier plan of the integration owner. When using your private app in their Zaps, users' Zap runs will be [held](https://help.zapier.com/hc/en-us/articles/8496291148685-View-and-manage-your-Zap-history) if the cumulative calls across all users of your private integration exceed the following limits on the integration owner's plan:
* Free and Professional plans: 100 calls every 60 seconds.
* Team and Enterprise plans: 5000 calls every 60 seconds.
* To increase a private integration rate limit for your users, [upgrade your Zapier plan](https://help.zapier.com/hc/en-us/articles/8496277302157-Change-or-cancel-your-Zapier-plan).
* To request an increase in the rate limit for your private integration beyond 5000 calls, contact our [Sales team](https://zapier.com/l/contact-sales).
* You can have up to [100 admins and collaborators](/platform/manage/add-team).
* You can invite up to [100 users by email](/platform/manage/sharing#2-invite-users-by-email). There's no limit when [sharing access using a public link](/platform/manage/sharing#1-invite-users-with-a-public-link), but note this access cannot be revoked once a user accepts the invitation link.
* [Embedding](https://platform.zapier.com/embed/overview) Zapier and [Zap templates](/platform/publish/zap-templates) are not supported.
* [Sharing a template of Zaps](https://help.zapier.com/hc/en-us/articles/8496292155405-Share-a-copy-of-your-Zap) is not supported.
* Your app won't appear as an option on [Zapier's ChatGPT plugin](https://help.zapier.com/hc/en-us/articles/14058263394573).
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Recommended triggers and actions
Source: https://docs.zapier.com/platform/quickstart/recommended-triggers-and-actions
Whether you’re just starting to scope out a new Zapier integration build or have successfully launched your app in the Zapier App Directory, it’s helpful to know what features users find the most valuable and are the most widely used across Zapier’s various [app categories](https://zapier.com/apps). Ensuring your integration covers the foundational triggers, actions, and searches applicable to your app will provide more utility to your users.
## Top Triggers, Actions, and Searches by App Category
The lists provided do not encompass every possible model or object specific to individual apps. Rather, they represent a more general overview of the most frequently observed ones in each category to serve as a guide to apply to your own app. Remember to maintain consistent terminology between your Zapier integration and app platform so users have a clear connection between the two.
Maybe your CRM platform, refers to new entries as *Contacts*. On another, they could be called *Leads*, *Clients*, *Persons*, or any term unique to the platform, such as *Hoomans* or *Zaperonis*. You may not find *Zaperonis* listed below, but if you see a similar concept like a *New Contact* trigger, you can apply the same logic with a *New Zaperoni* trigger for your integration.
If you don’t see a list for your specific category, there may not have sufficient integrations within it to surface best practices. Reach out to [Partner support](https://developer.zapier.com/contact) to request a category.
### Accounting
| Triggers | Actions | Searches | Search or Creates |
| --------------------------- | --------------------------------- | ---------------------------- | -------------------------------------- |
| New Payment | Create Customer/Contact/Client | Find Invoice | Find or Create Customer/Client/Contact |
| New Invoice/Bill | Create Invoice/Bill | Find Customer/Client/Contact | |
| New Expense | Send Invoice | | |
| New Customer/Contact/Client | Create Payment/Sale/Sales Receipt | | |
| New Quote/Estimate | | | |
View [example apps](https://zapier.com/apps/categories/accounting).
### Ads & Conversions
| Triggers | Actions | Searches | Search or Creates |
| ------------------------- | ----------------------------------- | -------- | ----------------- |
| New Lead/Subscriber/Visit | \*Send Event/Conversion/Measurement | | |
| New Form Response/Entry | Add Contact/Email to List/Audience | | |
\*Be sure your actions cover all types of events or conversions your app supports, such as ‘offline’, ‘lead’, ‘funnel’, etc.
View [example apps](https://zapier.com/apps/categories/ads-conversion).
### AI Tools
| Triggers | Actions | Searches | Search or Creates |
| --------------------------------------------- | ----------------------------------------------- | -------- | ----------------- |
| (Chat) New Message | Send Prompt | | |
| New Transcription/Recording/Video/Image Ready | Request/Generate Image/Transcription/Video/etc. | | |
View [example apps](https://zapier.com/apps/categories/ai-tools).
### Bookmark Managers
| Triggers | Actions | Searches | Search or Creates |
| ------------------ | ---------------------- | -------- | ----------------- |
| New Item/Bookmark | Bookmark/Add Page/Item | | |
| New Favorited Item | | | |
| New Tagged Item | | | |
View [example apps](https://zapier.com/apps/categories/bookmarks).
### Calendar
| Triggers | Actions | Searches | Search or Creates |
| --------------------- | --------------------- | ---------- | -------------------- |
| New Event/Meeting | Create Event | Find Event | Find or Create Event |
| Event Started | Add Attendee to Event | | |
| Updated Event/Meeting | | | |
View [example apps](https://zapier.com/apps/categories/calendar).
### Call Tracking
| Triggers | Actions | Searches | Search or Creates |
| --------------------- | ------- | -------- | ----------------- |
| Call Completed | | | |
| New Call/Call Started | | | |
| Call Tagged | | | |
View [example apps](https://zapier.com/apps/categories/call-tracking).
### Contact Management
| Triggers | Actions | Searches | Search or Creates |
| ------------------------------- | ---------------------------------- | -------------------------------- | ------------------------------------------ |
| New Contact/Lead/Person/Company | Create Contact/Lead/Person/Company | Find Contact/Lead/Person/Company | Find or Create Contact/Lead/Person/Company |
| New Form Submission/Entry | Add Contact to Group/Tag/List | | |
| | Update Contact/Lead/Person/Company | | |
View [example apps](https://zapier.com/apps/categories/contacts).
### Customer Support
| Triggers | Actions | Searches | Search or Creates |
| -------------------------------- | ---------------------------------- | -------------------------------- | --------------------------------- |
| Tag Added to Customer/User/Lead | Create Ticket/Request/Conversation | Find Customer/User/Lead | Find or Create Customer/User/Lead |
| New Ticket/Request | Update Ticket/Request/Conversation | Find Ticket/Request/Conversation | |
| New Customer/User/Lead | Add/Remove Tag on User/Ticket/Lead | | |
| New Chat/Message/Conversation | Send Message | | |
| New Closed/Finished Conversation | Update Customer/User/Lead/Company | | |
| | Add Comment/Note on Ticket/Request | | |
| | Create Customer/User/Lead/Company | | |
View [example apps](https://zapier.com/apps/categories/customer-support).
### CRM (Customer Relationship Management)
| Triggers | Actions | Searches | Search or Creates |
| -------------------------------- | ------------------------------------------------ | -------------------------------- | ------------------------------------------ |
| \*New Record/Module Entry | \*Create Record/Module Entry | \*Find Record/Module Entry | \*Find or Create Record/Module Entry |
| New Contact/Lead/Person/Company | \*Update Record/Module Entry | Find Lead/Contact/Person/Company | Find or Create Lead/Contact/Person/Company |
| New Deal/Opportunity/Job/Inquiry | Create Contact/Lead/Person/Company | Find Deal/Opportunity | Find or Create Deal/Opportunity |
| Tag Added or Removed | Update Contact/Lead/Person/Company | | |
| \*\*Updated Record/Module Entry | Create Deal/Opportunity | | |
| Updated Deal/Opportunity Status | Update Deal/Opportunity | | |
| Updated Lead Status | Create Note | | |
| Updated Project Status | Add Contact/Lead to Campaign/Group | | |
| | Create Activity/Event | | |
| | Add Tag to X (i.e. Contact, Record, Opportunity) | | |
\*Cover the most popular models of your platform at a minimum. You can create individual triggers, actions, and searches for each model such as, “New Customer”, “New Deal”, “Create Customer”, and “Create Deal”. Or create a singular trigger, action, and search that each support multiple models by requiring users to select which model they’re taking action on via an input field, such as “New Record” and “Create Record”.
\*\**Updated* triggers for CRMs are often most useful when users are able to specify which field(s) to watch for updates on, instead of triggering on any and all updates.
View [example apps](https://zapier.com/apps/categories/crm).
### Databases
| Triggers | Actions | Searches | Search or Creates |
| ------------------ | ----------------- | --------------- | ------------------------- |
| New Record/Row | Create Record/Row | Find Record/Row | Find or Create Record/Row |
| Updated Record/Row | Update Record/Row | | |
\*Zapier searches automatically return only the first result in the response. To return multiple results, [return the set of results](/platform/build/response-types) as an array of objects under a descriptive key.
View [example apps](https://zapier.com/apps/categories/databases).
### Documents
| Triggers | Actions | Searches | Search or Creates |
| ------------------------- | ------------------------------- | ------------- | ----------------------- |
| New Document | Create Document (from template) | Find Document | Find or Create Document |
| Document Completed/Signed | Add to Document | | |
| Document Status Updated | | | |
| Document Sent | | | |
View [example apps](https://zapier.com/apps/categories/documents).
### Drip Email
| Triggers | Actions | Searches | Search or Creates |
| ----------------------- | ----------------------------------------------------------------------- | ------------------------------------- | ----------------------------------------------- |
| New Subscriber/Prospect | Add/Remove Tag from Subscriber/Lead/Prospect/Contact | Find Subscriber/Lead/Prospect/Contact | Find or Create Subscriber/Lead/Prospect/Contact |
| New Tagged Subscriber | Create Subscriber/Lead/Prospect/Contact | | |
| New Unsubscribe | Update Subscriber/Lead/Prospect/Contact | | |
| New Reply | Add Subscriber/Lead/Prospect/Contact to Sequence/Campaign/List/Audience | | |
View [example apps](https://zapier.com/apps/categories/drip-emails).
### eCommerce
| Triggers | Actions | Searches | Search or Creates |
| ------------------------------- | --------------- | ------------- | ----------------------- |
| New Order/Purchase/Sale | Create Order | Find Order | Find or Create Customer |
| New Paid Order/Payment Received | Create Customer | Find Customer | |
| Abandoned Cart | Create Product | Find Product | |
| New Customer | | | |
View [example apps](https://zapier.com/apps/categories/ecommerce).
### Email
| Triggers | Actions | Searches | Search or Creates |
| -------------------------------- | ------------------ | ---------- | ---------------------- |
| New Email Matching Search | Send Email | Find Email | Find or Create Email |
| New Email | Create Draft Email | | Find or Create Contact |
| New Labeled/Tagged/Starred Email | Create Contact | | |
| New Attachment | | | |
| | | | |
View [example apps](https://zapier.com/apps/categories/email).
### Email Newsletters
| Triggers | Actions | Searches | Search or Creates |
| ------------------------------------------- | ------------------------------------------ | ----------------------- | --------------------------------- |
| New Subscriber/Contact in List/Audience/Tag | Create Subscriber/Contact | Find Subscriber/Contact | Find or Create Subscriber/Contact |
| New Subscriber/Contact | Send Email/Campaign | | |
| Email Opened/Link Clicked | Add/Subscribe Contact to List/Audience/Tag | | |
| | Update Subscriber/Contact | | |
View [example apps](https://zapier.com/apps/categories/email-newsletters).
### Event Management
| Triggers | Actions | Searches | Search or Creates | |
| ------------------------- | ------------------------------ | -------- | ----------------- | - |
| New Registrant/RSVP | Create Attendee/Add Registrant | | | |
| New Order/Booking/Ticket | Create Event | | | |
| New Event | Create Event | | | |
| New Attendee/Contact/Lead | | | | |
View [example apps](https://zapier.com/apps/categories/event-management).
### File Management & Storage
| Triggers | Actions | Searches | Search or Creates |
| ------------------ | ------------- | ----------- | --------------------- |
| New File in Folder | Upload File | Find File | Find or Create Folder |
| New Folder | Create Folder | Find Folder | |
| New File | Create File | | |
| Updated File | Move File | | |
View [example apps](https://zapier.com/apps/categories/files).
### Forms & Surveys
| Triggers | Actions | Searches | Search or Creates |
| ---------------------------------- | ------------------------------------- | ----------------------------------- | ----------------- |
| New Entry/Form Response/Submission | Create Entry/Form Response/Submission | Find Entry/Form Response/Submission | |
| New Lead | Send Form | | |
View [example apps](https://zapier.com/apps/categories/forms).
### Fundraising
| Triggers | Actions | Searches | Search or Creates |
| ------------------------------- | ---------------------------------- | ------------------------- | ----------------------------------- |
| New Donation/Transaction/Pledge | Create Member/Donor/Contact | Find Member/Donor/Contact | Find or Create Member/Donor/Contact |
| New Member/Donor/Contact | Create Donation/Transaction/Pledge | | |
View [example apps](https://zapier.com/apps/categories/fundraising).
### Marketing Automation
| Triggers | Actions | Searches | Search or Creates |
| ---------------------------------------------- | -------------------------------------------------- | ---------------------------- | -------------------------------------- |
| New Contact/Lead/Subscriber | Create Contact/Lead/Subscriber | Find Contact/Lead/Subscriber | Find or Create Contact/Lead/Subscriber |
| New Contact in List/Audience/Segment | Create Opportunity/Deal/Order | Find Deal | |
| Tag Added/Removed from Contact/Lead/Subscriber | Update Opportunity/Deal | | |
| Updated Deal/Pipeline Stage | Update Contact/Lead/Subscriberv | | |
| New Order/Purchase/Sale | Add Contact/Lead/Subscriber to Campaign/List/Group | | |
| New Form Entry/Submission | Add/Remove Tag fro Contact/Lead/Subscriber | | |
| Updated Contact/Lead/Subscriber | | | |
| | | | |
View [example apps](https://zapier.com/apps/categories/marketing-automation).
### Notes
| Triggers | Actions | Searches | Search or Creates |
| -------------------------------- | -------------- | -------- | ----------------- |
| New Note | Create Note | | |
| New Note in Notebook/Section/Tag | Append to Note | | |
View [example apps](https://zapier.com/apps/categories/notes).
### Notifications
| Triggers | Actions | Searches | Search or Creates |
| ------------------------ | ------------------------- | -------- | ----------------- |
| New Notification/Message | Send Notification/Message | | |
View [example apps](https://zapier.com/apps/categories/notifications).
### Online Courses
| Triggers | Actions | Searches | Search or Creates |
| ------------------------------------ | ------------------------------------------------- | ----------------- | --------------------------- |
| New Order/Sale/Purchase/Subscription | Enroll User/Add User to Course | Find User/Student | Find or Create User/Student |
| New Enrollment | Create Credentials/Grant Access/Issue Credentials | | |
| Course/Lesson Completed | Subscribe User to List/Add User to Group | | |
| New User/Student | Unenroll User/Student | | |
View [example apps](https://zapier.com/apps/categories/it-operations-education).
### Payment Processing
| Triggers | Actions | Searches | Search or Creates |
| ----------------------------------------------- | ----------------------------------- | -------------------------------- | ----------------------- |
| New Payment or Payment Paid | Create Customer | Find Invoice/Payment/Transaction | Find or Create Customer |
| New Subscription/Order/Sale/Transaction/Invoice | Create Payment Link (if applicable) | Find Customer | |
| New Customer | Update Customer | Find Subscription | |
| Canceled Subscription/Order/Sale | | | |
| Failed Payment | | | |
| New Refund | | | |
View [example apps](https://zapier.com/apps/categories/payment-processing).
### Phone & SMS
| Triggers | Actions | Searches | Search or Creates |
| ------------------------ | ----------------- | ------------------------------ | ---------------------- |
| New SMS/Message Received | Send SMS/Message | Find Contact (by phone number) | Find or Create Contact |
| New Call | Create Contact | | |
| New Recording | Update Contact | | |
| Call Completed | Call Phone Number | | |
View [example apps](https://zapier.com/apps/categories/phone).
### Product Management
| Triggers | Actions | Searches | Search or Creates |
| ----------------------------------- | ----------------------------- | -------- | ----------------- |
| New Feedback/Form Submitted/Request | Create Note/Feature/Task/Idea | | |
| New Note/Comment | | | |
View [example apps](https://zapier.com/apps/categories/product-management).
### Project Management
| Triggers | Actions | Searches | Search or Creates |
| -------------------------------- | ----------------------------------- | -------------------- | ------------------------------ |
| New Task/Item/Issue | Create Task/Item/Issue | Find Task/Item/Issue | Find or Create Task/Item/Issue |
| Task/Item/Issue Status Changed | Update Task/Item/Issue | Find User | Find or Create Project/Board |
| New Label/Tag on Task/Item/Issue | Add Comment/Note to Task/Item/Issue | Find Project/Board | |
| Completed Task/Item/Issue | | | |
| New Event/Activity | | | |
| Updated Task/Item/Issue | | | |
View [example apps](https://zapier.com/apps/categories/project-management).
### Proposal & Invoice Management
| Triggers | Actions | Searches | Search or Creates |
| -------------------------------- | ------------------------------ | ---------------------------- | ---------------------------------- |
| Proposal/Estimate/Quote Accepted | Create Client/Contact/Lead | Find Client/Contact/Lead | Find or Create Client/Contact/Lead |
| Proposal Signed | Create Proposal/Estimate/Quote | Find Proposal/Estimate/Quote | |
| Proposal Won | Create Invoice | | |
| Proposal Sent | Create Project | | |
| New Proposal/Estimate/Quote | | | |
View [example apps](https://zapier.com/apps/categories/invoices).
### Scheduling & Booking
| Triggers | Actions | Searches | Search or Creates |
| ------------------------------- | -------------------------------------- | ------------------------ | --------------------- |
| New Client/Customer | Create Client/Customer | Find Booking/Appointment | Find or Create Client |
| New Booking/Appointment | Create Booking/Appointment/Request/Job | | |
| New Cancellation | | | |
| Rescheduled Booking/Appointment | | | |
View [example apps](https://zapier.com/apps/categories/scheduling).
### Server Monitoring
| Triggers | Actions | Searches | Search or Creates |
| -------------------------------------- | --------------------- | ---------------------------- | ----------------- |
| New or Updated Ticket/Request/Incident | Create Alert | Find Ticket/Request/Incident | |
| New Alert | Create Ticket/Request | | |
View [example apps](https://zapier.com/apps/categories/server-monitoring).
### Signatures
| Triggers | Actions | Searches | Search or Creates |
| --------------------------- | -------------------------- | ---------------------- | ----------------- |
| Document/Contract Sent | \*Create Document/Contract | Find Document/Contract | |
| Document/Contract Completed | Send Signature Request | | |
| Document/Contract Signed | | | |
\**Create Document/Contract* actions typically allow for users to select a template in the action’s setup.
View [example apps](https://zapier.com/apps/categories/signatures).
### Social Media Accounts
| Triggers | Actions | Searches | Search or Creates |
| ------------------------------ | ------------------------- | -------- | ----------------- |
| New Post/Message/Media (by me) | Create Post/Message/Media | | |
| New Post/Message/Media | | | |
View [example apps](https://zapier.com/apps/categories/social).
### Spreadsheets
| Triggers | Actions | Searches | Search or Creates |
| ----------- | -------------- | ------------------------------------ | ------------------ |
| New Row | Create/Add Row | Find Row | Find or Create Row |
| Updated Row | Create Row(s) | Find Row(s) (with line-item support) | |
| | Update Row | | |
View [example apps](https://zapier.com/apps/categories/spreadsheets).
### Task Management
| Triggers | Actions | Searches | Search or Creates |
| -------- | ----------- | --------- | ------------------- |
| New Task | Create Task | Find Task | Find or Create Task |
| | Update Task | | |
View [example apps](https://zapier.com/apps/categories/todo-lists).
### Team Chat
| Triggers | Actions | Searches | Search or Creates |
| ----------------------- | --------------------------- | ------------------------------------ | ----------------- |
| New Message in Channel | Send Channel Message | Find User (by email, name, username) | |
| New Reaction on Message | Send Direct/Private Message | | |
View [example apps](https://zapier.com/apps/categories/team-chat).
### Time Tracking Software
| Triggers | Actions | Searches | Search or Creates |
| ---------------------------- | ----------------- | ----------- | ---------------------- |
| New Time Entry | Start Time Entry | Find Client | Find or Create Client |
| New Time Entry/Timer Started | Create Time Entry | | Find or Create Project |
| | Create Project | | |
| | Create Client | | |
| | Create Task | | |
View [example apps](https://zapier.com/apps/categories/time-tracking).
### Transactional Emails
| Triggers | Actions | Searches | Search or Creates |
| ------------------ | ------------ | -------- | ----------------- |
| Failed Delivery | \*Send Email | | |
| Bounced Email | | | |
| Open/Clicked Event | | | |
\**Send Email* actions often allowed users to select and use a template in the action’s setup.
View [example apps](https://zapier.com/apps/categories/transactional-email).
### Transcription
| Triggers | Actions | Searches | Search or Creates |
| -------------- | ----------------------------------------- | -------- | ----------------- |
| New Transcript | Create Transcription/Upload Audio or File | | |
View [example apps](https://zapier.com/apps/categories/transcription).
### Video & Audio
| Triggers | Actions | Searches | Search or Creates |
| --------------------------------- | ----------------------- | ---------- | ----------------- |
| New Video (in Channel/Playlist) | Upload Video | Find Track | |
| New Track in Playlist/Saved Track | Add Listener/Subscriber | | |
| | Add Track to Playlist | | |
View [example apps](https://zapier.com/apps/categories/video).
### Video Conferencing
| Triggers | Actions | Searches | Search or Creates |
| -------------- | --------------------- | -------- | ----------------- |
| New Recording | Create/Add Registrant | | |
| New Registrant | Create Meeting | | |
View [example apps](https://zapier.com/apps/categories/video-calls).
### Webinars
| Triggers | Actions | Searches | Search or Creates |
| ------------------------------------ | ------------------------------ | --------------- | ----------------- |
| New Registration/Registrant | Create Registration/Registrant | Find Registrant | |
| New Attendee or Webinar/Event Joined | Register to an Event | Find Session | |
| Attendee Stays Until/% of time | | | |
View [example apps](https://zapier.com/apps/categories/webinars).
### Website Builders
| Triggers | Actions | Searches | Search or Creates |
| ---------------------------------- | ------------------------- | -------- | ----------------- |
| New Form Submission/Review/Message | Create Post/Content | | |
| New Member/User/Lead | Create/Invite User/Member | | |
| New Post/Content | | | |
View [example apps](https://zapier.com/apps/categories/cms).
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we’ll connect you with the right resource or contact support.*
# Platform UI tutorial
Source: https://docs.zapier.com/platform/quickstart/ui-tutorial
This tutorial walks you through the process of building an integration on Zapier with authentication, a trigger and an action using the Platform UI.
## Prerequisites
* You'll need a [Zapier account](https://zapier.com/sign-up).
* If you haven't used Zapier before, you'll want to learn the basics in our [Zapier Getting Started Guide](https://zapier.com/learn/zapier-quick-start-guide/).
* Familiarity with [APIs](https://zapier.com/resources/guides/apis)
* Select an API with public documentation, whether your own app's API or an app you're familiar with as a user.
## 1. Start an integration
To add an integration:
* Go to [https://developer.zapier.com/](https://developer.zapier.com/).
* Log into your Zapier account.
* Click **Start a Zapier Integration**.
* Next, you will be ask to provide information about your integration:
* **Name**: Add the name of your integration.
* **Description**: Add a description the app in 140 characters or less.
* **Homepage URL**: Add the homepage URL of your app. The domain will be used as the email domain to allow team members to [join your integration as a collaborator](/platform/manage/add-team).
* **Logo**: Upload a square, transparent PNG image of your app logo. The image must be at least 256x256px in size, and doesn't include the app name. Learn more in [branding guidelines](/platform/publish/branding-guidelines).
* **Intended Audience**: From the dropdown menu, select if you are building a [public or private integration](/platform/quickstart/private-vs-public-integrations).
* **Role**: Select your relationship with the app you're integrating with Zapier from the dropdown menu.
* **Category**: Select how you would categorize your app from the dropdown menu.
* Once you have completed adding details your integration, click **Create**.
## 2. Add authentication
[Authentication](/platform/build/auth) defines how Zapier's platform authenticates with the app's API you're connecting to, collecting and storing user data to allow access to their accounts. Zapier supports the following authentication schemes:
Refer to the API documentation for the app you're building with to choose the correct authentication scheme for your API. Add the authentication fields for the input form your users will see when connecting their app account to Zapier.
Move through each configuration step of your chosen authentication scheme, adding the relevant endpoint to be used as the authorization URL to exchange the credentials supplied by the user for authentication. Depending on your API's authentication method, you may also need to configure Zapier-provided application credentials in your app's developer settings.
## 3. Add a trigger
[Triggers](/platform/build/trigger) allow users to start Zapier workflows when something is added or updated in the app.
Add settings for how your trigger displays to users, any optional input fields, and connect the app's API in the API Configuration tab.
If the API you're building with supports REST Hooks, you can configure your trigger to create a unique subscription from every Zap to your app that will run in near real-time and send events to Zapier as they occur in your app.
Alternatively, configure a polling trigger that automatically polls the URL you've provided for new data every 1 to 15 minutes, depending on the user's Zapier plan. An appropriate polling endpoint will return results in reverse chronological order to make sure new or updated items can be found on the first page of the results. Polling an endpoint most commonly uses a GET request.
The default *Form Mode* allows you to add API endpoint URLs, choose the API call type, and include any authentication details and input form data with the API call.
The optional toggle into [*Code Mode*](/platform/build/code-mode) converts everything entered in the API request form to JavaScript code and is an advanced feature beyond the scope of this tutorial.
## 4. Add an action
[Actions](/platform/build/action) allow users to create, search, or update records in your app through your API. In general, delete actions are not recommended for integrations.
Add settings for how your action displays to users, and at least one input field and connect the app's API in the API Configuration tab.
Refer to the API documentation for your app to choose a frequently used record with an available endpoint and add a create action that will add an record in your app when tested. Creating a new record most commonly uses a POST request.
## 5. Test your integration
When building an integration, it's important to test the functionality of your authentication, triggers, and actions in the Platform UI and also in the [Zap editor](https://zapier.com/editor/). In the Zap editor, you'll see how users of your integration will create Zaps using your triggers, and actions.
Learn more about [testing your integration](/platform/build/test-auth).
## 6. (Optional) Validate your integration
[Run automated checks](/platform/publish/integration-checks-reference) to identify errors and recommendations on how to improve the user experience of your integration.
These checks are only required to pass if you are building a public integration, but they are also useful to identify suggestions for future updates to any integration.
## 7. (Optional) Invite team members
Integrations are not owned by individuals, but rather by teams. You can invite team members to collaborate with in the Platform UI as either an admin or a collaborator.
Learn more about [adding team members](/platform/manage/add-team) to your integration.
## 8. (Optional) Share your integration
Once you have at least one trigger or action, you'll want to share your integration with some users. Early feedback helps make sure you're building functionality that will be used.
You can [share your integration with users](/platform/manage/sharing) by a public link or by email.
Note: [Public integrations](/platform/quickstart/private-vs-public-integrations) can be accessed by any Zapier user and doesn't require users to be specially invited.
## 9. Modify your integration
If you need to make any changes to your integrations, you can do so by creating [a new version](/platform/manage/versions). Versions helps to track and manage changes to your integration over time.
Public integrations or private integrations with more than 5 users **must have** a new version to make any edits. It is still recommended to make changes for private integrations with fewer than 5 users in a new version as well and [consider Zapier's best practices](/platform/manage/planning-changes) when doing so.
## Learn more
* Recommended features for your integration [by app category](/platform/quickstart/recommended-triggers-and-actions).
* [Step-by-step tutorial](https://community.zapier.com/featured-articles-65/zapier-platform-ui-a-complete-guide-on-how-to-integrate-with-github-26298#post108889) that uses the GitHub API.
* About [different types of support](/platform/quickstart/get-help) available to help you build your integration.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Platform UI vs Platform CLI
Source: https://docs.zapier.com/platform/quickstart/ui-vs-cli
There are two different developer tools to build either private or public integrations with on the Zapier Developer Platform: Platform UI or Platform CLI.
## Platform UI
Platform UI is the visual way for users with API experience to build integrations in a web app editor. It allows for some advanced calls and response parsing when using Code mode; but is predominantly designed for builders more comfortable with a visual form editor than working in code.
To get started, check out the following resources:
* [Quick start guide to using Platform UI](/platform/quickstart/ui-tutorial)
* [Tutorial using Github's API to build with the Platform UI](https://community.zapier.com/featured-articles-65/zapier-platform-ui-a-complete-guide-on-how-to-integrate-with-github-26298#post108889)
## Platform CLI
Platform CLI is a terminal-based app that allows builders to scaffold new integrations locally, using standard JavaScript in your local development environment and code editor. It allows for custom coding for API calls, middleware, file support and other advanced functionality. It's the preferred tool for engineers comfortable with a standard development workflow and collaborating in a local environment using GIT version control before pushing integration versions to the Zapier server. Platform CLI can be more difficult to use for non-engineers, but will likely be more efficient for an engineering team.
To get started, check out the following resources:
* [Quick start guide to using Platform CLI](/platform/quickstart/cli-tutorial)
* [Tutorial using Github's API to build with Platform CLI](https://developer.zapier.com/cli-guide/introduction)
* [CLI documentation](/platform/build-cli/overview)
## Comparison between developer tools
You can accomplish the same goals and build equally powerful Zapier integrations with both Platform UI and Platform CLI. The best tool for your integration depends on your work style and integration needs.
Below you can review what is capable between both developers tools
| Authentication | Platform UI | Platform CLI |
| ---------------------- | --------------------- | --------------------- |
| Basic Authentication | | |
| Session authentication | | |
| API Key | | |
| Custom | | |
| OAuth v1 | | |
| OAuth v2 | | |
| Digest | | |
| Triggers | Platform UI | Platform CLI |
| ------------------------------------------ | --------------------- | --------------------- |
| REST Hooks | | |
| Polling triggers | | |
| Support for static webhooks | | |
| Customize request handling with JavaScript | | |
| Search Actions | Platform UI | Platform CLI |
| ------------------------------------------ | --------------------- | --------------------- |
| Search or create functionality | | |
| Customize request handling with JavaScript | | |
| Create Actions | Platform UI | Platform CLI |
| ------------------------------------------ | --------------------- | --------------------- |
| Customize request handling with JavaScript | | |
| Advanced | Platform UI | Platform CLI |
| ---------------------------------------------- | ----------- | --------------------- |
| Custom middleware | | |
| Resources | | |
| File support | | |
| Hydration | | |
| Import and use NPM modules | | |
| Organize code with common functions | | |
| Handling long running tasks via a callback URL | | |
| Testing and Workflow | Platform UI | Platform CLI |
| ---------------------------------- | --------------------- | --------------------- |
| GUI with form-based editor | | |
| WYSIWYG form preview | | |
| Write custom automated test suites | | |
| Add team members to project | | |
| Manage testers | | |
| Monitor usage | | |
| View logs | | |
| Manage versions | | |
| Use custom source code manager | | |
| Export integration to CLI | | - |
If you are still unsure after reviewing our comparsion tables, Zapier advises to build with the Platform UI.
## Switching between developer tools
### Platform UI to Platform CLI
Yes, it is possible to switch your integration from Platform UI to Platform CLI.
You can [export](/platform/manage/export-cli) an existing Platform UI integration to Platform CLI. Once exported, you can customize your integration in your local development environment. You will still have access to view your integration in the Platform UI.
Before making this change, Zapier recommends learning more about possible user impacts when [making changes to your integration](/platform/manage/planning-changes).
### Platform CLI to Platform UI
It's not possible to directly export an integration from Platform CLI to Platform UI.
You would need to create a new integration **version** built in the Platform UI (do not create an entirely new app). Existing users would most likely need to manually update their Zaps to use the new version. Learn more about [this process and best practices to minimize user impact](/platform/manage/export-ui) and contact [Developer Support](https://developer.zapier.com/contact) with any questions.
***
*Need help?* [Tell us about your problem](https://developer.zapier.com/contact) *and we'll connect you with the right resource or contact support.*
# Zapier integration structure
Source: https://docs.zapier.com/platform/quickstart/zapier-integration-structure
[Zapier's Developer Platform](https://developer.zapier.com/) includes everything needed to build and manage a new Zapier integration. When you access your integration project by name, you'll see the left sidebar outlines the core project structure.
### Dashboard
*Dashboard* tab is used to see your Partnership level, active user total count, overall embed status and [integration health score](/platform/publish/partner-program#integration-health-score). You **must** be an [admin or collaborator](/platform/manage/add-team) to view an integration's dashboard.
### Insights
*Insights* tab is used to monitor and analyze your integration's growth, usage, and detailed embed metrics. You **must** be an [admin or collaborator](/platform/manage/add-team) to view an integration's insights.
### Build
*Build* tab defines your integration:
* *Version Overview* shows the outline of the version selected in the [dropdown](https://cdn.zappy.app/ca49500dc40cd1986693223661ab22b2.png)
* *Authentication* sets how users authenticate with your API; using basic, API key, digest, session, or OAuth v2 authentication.
* *Triggers* control how Zapier gets data from your API into a Zap, with `GET` HTTP calls or REST Hooks.
* *Actions* control how Zapier sends data to your API, including:
* *Create Actions* to send new data from a Zap to your API, with `POST` or `PUT` HTTP calls to create or update items.
* *Search Actions* to perform lookups through your API using `GET` calls.
* *Advanced* manages environment variables to store secret values your integration needs to communicate with your API, such as API keys or client IDs and secrets, or manage switching between staging and production environments in a version.
When planning your integration build, think through your integration and what features from your app your users might find the most valuable. Review [integration design examples](/platform/quickstart/must-have-triggers-and-actions) by app category for inspiration.
Walk through building an integration with the [UI tutorial](/platform/quickstart/ui-tutorial) or the [CLI tutorial](/platform/quickstart/cli-tutorial).
### Manage
*Manage* tab is where you access tools to maintain your integration:
* *Versions* gives an [overview of each version's status](/platform/manage/versions), user activity and for published apps; the changelog included in a promotion
* *Sharing* is where you [give users access](/platform/manage/sharing) to private versions via an invite link to all versions or an email invite to a specific version
* *Manage Team* is used to [add team members](/platform/manage/add-team) to manage your integration
* *Monitoring* gives access to [logs for requests](/platform/build/test-monitoring#steps) made to your API by your Zapier integration
* *History* shows the 50 most recent audit logs for changes to your integration
* *Bugs & Feature Requests* are reported by users for published apps and should be used to communicate on these issues with Zapier Developer Support
### Embed
*Embed* tab shows for [public integrations](/platform/quickstart/private-vs-public-integrations) only and describes a [variety of ways](https://platform.zapier.com/embed/full-zapier-experience) to surface your Zapier integration directly within your own product. It allows your users to search for apps that connect with yours, see popular workflows used with your app, and (most importantly) enables them to sign up for Zapier, build Zaps and edit them, too — without leaving your product.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# AI Actions
Source: https://docs.zapier.com/platform/reference/ai-actions
Zapier's [AI Actions](https://actions.zapier.com/) is an AI alpha product designed to work with natural language-based products. It leverages the Zapier platform, with over [6000 apps](https://zapier.com/apps). You can include the capabilities of Zapier's platform in your own product.
With the Natural Language Actions API, you can:
* Access Zapier's platform of 6000+ apps within your own product.
* Integrate with chatbots or [large language models](https://en.wikipedia.org/wiki/Large_language_model).
* Power any integration project.
Learn more in our [AI Actions documentation](https://actions.zapier.com/).
## Get access to the AI Actions API
AI Actions API is available for any Zapier partner or developer to build on.
It's free to use by visiting our [Getting Started with AI Actions page](https://actions.zapier.com/).
> **Note**: By signing up for API access, you agree to [Zapier's Platform Agreement](https://zapier.com/platform/tos) and [Privacy Policy](https://zapier.com/privacy).
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Zapier integration structure for an AI app
Source: https://docs.zapier.com/platform/reference/ai-app
AI app integrations built on Zapier allow users to automate tasks using AI capabilities. Here are some common pain points and recommendations when building AI apps on Zapier.
## Pain Points
### 1. Long-Running Actions
**Pain Point:** Actions that take a long time to process can cause issues, especially with Zapier's execution time limits. Test steps in the Zapier editor are limited to 50 seconds, and live Zap executions default to 30 seconds.
**Recommendations:**
* Use `z.generateCallbackUrl()` and `performResume`
* `z.generateCallbackUrl()`: This method generates a callback URL that your service can call once the long-running task is complete.
* `performResume`: This function allows the action to pause until the callback URL is called, resuming once the task is complete.
* **Why:** These tools help handle tasks that exceed Zapier's execution time limits by offloading the wait to an external service and resuming only when the task is done.
* [Documentation](/platform/build-cli/core#z-generatecallbackurl)
### 2. Handling Samples for Long-Running Tasks
**Pain Point:** Generating accurate samples for long-running tasks can be tricky, especially during the initial setup.
**Recommendation:**
* Use `bundle.meta.isLoadingSample`:
* When `bundle.meta.isLoadingSample` is true, return a simplified or cached version of the data that represents a typical response.
* **Why:** This approach ensures that users get a quick response during setup, avoiding delays caused by the actual long-running task.
* [Documentation](/platform/build-cli/core#bundle-meta)
### 3. Hiding Complex Fields in Actions
**Pain Point:** Complex configuration fields can overwhelm users, making the setup process cumbersome.
**Recommendation:**
* Use Custom Input Fields:
* You can create an input field that depends on another. For example, you could create an “Advanced Features” input field at the bottom of all of your other ones that has the property `altersDynamicFields: true` so when it's updated, all of the other fields refresh. Then any additional input fields could be dependent on whether that “Advanced Features” input field is true, then display the more advanced ones that are not necessarily required for all users. (ie. `if (bundle.inputData.advanced === true)`)
* These custom input fields can hide complex fields behind simpler user interfaces.
* **Why:** Simplifying the user interface makes it more user-friendly, leading to a better experience and fewer setup errors.
* [Documentation](/platform/build-cli/core#custom-dynamic-fields)
### 4. Use-Case Specific Actions
**Pain Point:** Users may struggle with setting up generalized actions that require specific configurations.
**Recommendations:**
* Create Use-Case Specific Actions:
* For example, a “ChatGPT Summarize Text” action can hide the configuration and prompt details behind the scenes. This can be accomplished by hardcoding a prompt into the action configuration itself and then just have the user input the text that needs to be summarized.
* Why: Pre-configured actions tailored to specific use cases streamline the user experience, making it easier for users to set up and use your app effectively.
* Create Use-Case Specific Dropdown:
* For example, a “Send Prompt” action could have a dropdown of available “use-cases” that when selected, pre-fill input fields for the user. This can be accomplished by having a mapping of sorts for your use-cases and some complex logic using `altersDynamicFields: true` to then have all of your input fields as custom ones which are loaded in via functions based on the the use-case selected and the default of them pre-filled.
* **Why:** Pre-configured AI prompts tailored to specific use cases streamline the user experience, making it easier for users to set up and use your app effectively and for them to understand how the AI is working where they could then tweak the prompt/other input fields themselves if need be.
* [Documentation](https://github.com/zapier/zapier-platform/blob/main/packages/schema/docs/build/schema.md#fieldschema)
### 5. Value of Zap Templates
**Pain Point:** Users often need help figuring out how to set up Zaps for common use cases.
**Recommendation:**
* Provide [Zap Templates](/platform/publish/zap-templates):
* Create templates for common use cases with pre-mapped variables and good starter prompts.
* **Why:** Templates serve as a starting point, helping users quickly set up their Zaps without having to configure everything from scratch.
By addressing these pain points with the recommended strategies, you can significantly improve the user experience and functionality of AI apps on the Zapier platform. For detailed guidance and support, always refer to the [Zapier Developer Documentation](https://platform.zapier.com/docs) or contact the [Zapier support team](https://developer.zapier.com/contact).
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Changelog
Source: https://docs.zapier.com/platform/reference/changelog
# CLI Command Reference
Source: https://docs.zapier.com/platform/reference/cli
# Cloning a version
Source: https://docs.zapier.com/platform/reference/cloning-a-version-tutorial
Cloning allows you to duplicate an existing version of your integration. This is particularly useful when you want to introduce new features or fixes without altering the original integration. When a previous version of your integration has more than 5 active users, you will need to clone that version to make modifications.
# Zapier integration structure for a CRM app
Source: https://docs.zapier.com/platform/reference/crm-app
CRM (customer relationship management) apps are detailed databases that link contacts with companies, companies with deals, and more.
To add a CRM app integration in the Platform UI:
## Prerequisites
* A [Zapier account](https://zapier.com/sign-up).
* If you haven't used Zapier before, you'll want to learn the basics in our [Zapier Getting Started Guide](https://zapier.com/learn/zapier-quick-start-guide/).
* Familiarity with your app's API documentation and available endpoints.
* Review the [Platform UI Tutorial](/platform/quickstart/ui-tutorial).
## 1. Add triggers for common record types in the CRM
* Check out the [common record types](/platform/quickstart/must-have-triggers-and-actions#crm-customer-relationship-management) used as triggers by other CRM apps.
* Build separate triggers for new and updated records. *Updated* triggers for CRMs are most useful when users are able to specify which field(s) to watch for updates on, instead of triggering on any and all updates.
* Include filter options if your app lets users add custom filters or views. Displaying an optional [dynamic dropdown](/platform/build/field-definitions#dynamic-dropdown) of the user's filters and ordering them by the most recently added is best practice.
## 2. Choose trigger type under API Configuration
### REST Hook trigger
* If your app supports webhook subscriptions that can be manipulated through a REST API, use [REST hooks](/platform/build/trigger#rest-hook-trigger) for your trigger to send new records to Zapier as soon as they are added to the CRM.
* Webhook triggers are marked as *Instant* [in the Zap Editor](https://cdn.zappy.app/6b696dfaf34664b181b6df651067cfd3.png).
* When your user has many app records created in a short space of time, webhooks make your integration more robust, preventing the possibility that a high number of new records will exceed the page size of polling results.
* With REST hooks, Zapier won't need to repeatedly poll your API to check for new responses.
### Polling trigger
* When using a Polling trigger, and for the *Perform List* URL for REST Hook triggers, the Polling URL should return the most recent record created or updated (if the trigger is an ‘Updated Record' trigger)
* If there are no recent new records, return an empty array. Zapier will then encourage the user to create a sample and re-test their trigger in the Zap Editor to finish mapping their Zap.
## 3. Additional considerations for Updated Record triggers
* Users expect updated triggers to run whenever a record has new data added, or when relational data is added or removed.
* For REST hook triggers, ensure that when relational data is reapplied to a record, your app sends Zapier that updated record.
* For polling triggers, to account for [deduplication](/platform/build/deduplication), you will need to customize your API call's code to ensure each record has a unique primary key (usually an `id` field). This could mean [copying a unqiue timestamp](/platform/build/deduplication#custom-primary-keys) to the `id` field or [setting `primary` to true](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#how-does-deduplication-work) for some output fields.
### Include linked information in trigger response
* CRM records are one part of a linked ecosystem of data. For example, if your trigger is “New Contact” and newly added contacts are linked to organizations, users expect to see full organization data, too.
* Include both IDs for linked data in the response output so they can be mapped to your app's action steps, as well as human-readable data such as individual fields for their name and contact info.
* If your record API endpoint does not automatically return additional linked data beyond the ID or name of the record, add custom code to your trigger API call to fetch relevant data linked to the record as well.
### Handle custom fields
* Use \[pagination]\((/platform/build/trigger#how-to-use-pagination) to retrieve custom fields a user might expect.
### Handle tags
* Return tags on records as either an array of strings or a comma-delimited list in a single string, for users to be be able to easily map them into other app actions.
## 4. Include common search actions
* Users expect to have searches for common records available for CRM integrations and for those searches to have parity with the fields returned for those same record triggers. For example, a user might have a *New Contact* trigger, and then want to find out more information about the organization the contact is associated with by using a *Find Organization* search. If the *New Contact* trigger only provides the associated organization ID, it doesn't make sense for the *Find Organization* search to only allow searches for the organization name.
* Configure the search to find an existing record, returning it in the same format the trigger returns records to give a consistent experience and allow the data to be used in the same manner in later actions.
* Offer multiple search key and value options where applicable.
* Prevent deduplication problems for unique fields (such as email) though, by offering only a single search query for that field instead of multiple options. This prevents users from searching on a different field, trying to create a new record, and seeing an error that a record with that email already exists.
* If a record cannot be found, do not return an error. Instead return a `200` success response with an empty array. That way, users can pair the search with a *Create* action to let users search for records and create them if they don't exist. Users will see a halted exception instead of an error.
\_ Read more about pairing [searches and creates](/platform/build/search-or-create).
## 5. Include common create actions
* Check out the [common record types](/platform/quickstart/must-have-triggers-and-actions#crm-customer-relationship-management) other CRM apps have create actions for.
* Use the standard *Create* or *Add* naming pattern to show users that this action creates a new record in your app
* Add corresponding *Update* actions with available *Search* actions to make it easier for users to update the correct record.
* Account for linked records in action input fields, so when your app's UI allows users to create a contact and link it to existing companies or stages, the same action is available through Zapier, via a [dynamic dropdown](/platform/build/field-definitions#dynamic-dropdown) to fetch linked record options and let users select them.
* Optionally link a [search connector](https://cdn.zappy.app/103626b1313602fa33c33711ed44ff56.png) to linked record input fields if users need to have the Zap find the correct related record, and map the found ID to the input field. To add that user prompt you'll need to work in the [Platform CLI](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#search-powered-fields).
* Do not have a single action create multiple records. When a user creates a new contact through Zapier, this should only create new contacts, and should not also create other linked records at the same time. Rather include a separate action to create the other linked record, along with a contact update action to link the contact after the other record is created. This reduces the chance for errors and record redundancy.
* Account for [custom fields in action input fields](/platform/build/dynamic-field), displaying the human-readable label instead of the internal ID.
* The first version of your integration doesn't need to have every possible action available, but add compatible functionality users expect or request in future updates.
## 6. Support in-app workflows
* If new records created in your app get automatically added to in-app workflows, sequences, follow-ups, or campaigns, make sure records created via the API by Zaps will also get automatically added to workflows.
* Optionally add a boolean field to your action input fields to let users select if they want this contact added to a workflow, or include a [dynamic dropdown](/platform/build/field-definitions#dynamic-dropdown) to select the workflow they want.
## 7. Test your triggers and actions
Make Zaps with the following criteria to ensure your app integration works as expected:
* Add a record in your app with many custom fields, and create a Zap to watch for new records to make sure each field is included when it triggers and is mappable in subsequent steps
* Create a multi-step Zap with at least one trigger, search, and action step where every step uses your app integration, to check the ease of linking one step to another.
* If you've included the option to link records in your integration's actions, verify these are linked correctly when creating records via a Zap.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Custom Actions and API Requests Actions
Source: https://docs.zapier.com/platform/reference/custom-actions-api-requests
[Custom Actions](https://help.zapier.com/hc/en-us/articles/16276574838925-App-Extensions-in-Zapier) and [API Requests](https://help.zapier.com/hc/en-us/articles/12899607716493-Set-up-an-API-request-action#prerequisites-0-0) are features that have been developed internally at Zapier, designed to help our mutual customers achieve the most value out of your app integration.
## What are Custom Actions and API Requests?
Custom Actions and API Requests enable Zapier users to build raw API requests with public APIs while leveraging your app integration's existing authentication protocol.
Since the launch, we've seen that the feature has been embraced and users are increasingly building and testing Custom Actions and API Requests. As customers build these requests, they may experience certain challenges with them – issues related to client permissions, malformed API URLs, or bad requests, for instance. These challenges, however, are neither unique nor unexpected, as they occur consistently in other similar settings like Zapier's built-in [Webhooks functionality](https://help.zapier.com/hc/en-us/sections/16074864820109-Webhooks-Code).
The Zapier support team stands ready to help users understand the feature and ensure it works as anticipated. However, it is essential for the user to correct and resolve the API error themselves, which is analogous to Zapier's support policy for Webhooks. This empowers users to receive the best experience from the platform while strengthening their skills.
## Can I enable Custom Actions and API Requests for my integration if it's not currently enabled?
As of July 1, 2024, we are not supporting Custom Actions or API Requests for new integrations. However, we are committed to enhancing the experience for all users. If you are interested in enabling Custom Actions or API Requests for your integration, we encourage you to contact our Platform Support Team via our [contact form](https://developer.zapier.com/contact). Your feedback is invaluable and helps us understand the significance of this feature for our partners.
## Can I opt-out of Custom Actions and API Requests if it's already enabled?
We currently aren't supporting an opt-out initiative. However, we are committed to bettering experiences for every user and encourage you to voice your concerns or feedback regarding this feature. Should you continue to experience any challenges or have specific pain points you're encountering, we would be glad to work on those to improve your experience.
We understand that you may have apprehensions regarding the potential support load, especially with respect to users building their own API requests. Be assured, we are dedicated to helping alleviate any impacts that this may cause. The primary goal is to empower users with more control over their API requests, presenting them with a richer experience and a superior level of customization. We believe our users derive significant value from these direct API requests.
Do not hesitate to reach out with more questions and feedback via our [contact form](https://developer.zapier.com/contact). We are always open to dialogue aimed at improving our services and our working relationship with our partners.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Using Dictionary Fields
Source: https://docs.zapier.com/platform/reference/dictionary-fields-tutorial
Dictionary fields allows your users to directly send an object with their provided value sets to your API.
# Creating dynamic dropdown fields
Source: https://docs.zapier.com/platform/reference/dynamic-dropdown-tutorial
Dynamic dropdown fields are useful when users need to select data from an existing list of similar data in their account on your app.
# Implementing Error Handling
Source: https://docs.zapier.com/platform/reference/error-handling-tutorial
Error handling enables you dictate how your integration should function when certain errors are returned from your API.
# Zapier integration structure for a forms app
Source: https://docs.zapier.com/platform/reference/forms-app
Form and survey app integrations built on Zapier allow users to connect mobile data collection forms to send the responses into other apps as new contacts, document templates, messages, and more.
To add a form or survey app integration in the Platform UI:
## Prerequisites
* A [Zapier account](https://zapier.com/sign-up).
* If you haven't used Zapier before, you'll want to learn the basics in our [Zapier Getting Started Guide](https://zapier.com/learn/zapier-quick-start-guide/).
* Familiarity with your app's API documentation and available endpoints.
* Review the [Platform UI Tutorial](/platform/quickstart/ui-tutorial).
## 1. Add a new entry/response trigger
* Start a new integration at [https://developer.zapier.com/](https://developer.zapier.com/) for your app
* Create a *New Form Entry/Submission* or *New Survey Response* trigger
* Use the standard *New* naming pattern to show users that this trigger retrieves new entries, not existing ones.
## 2. Configure selection of a specific form
* Add a [dynamic dropdown](/platform/build/field-definitions#how-to-add-dynamic-and-custom-fields) to retrieve form names exactly as they are listed in your app.
* If the endpoint the dropdown uses allows for sorting, you can `sort_by` the create date to order the dropdown list by the most recently added form to make it easier for users to select the form they need.
* Make the selection of a form required so the trigger only watches for results from this one form
* If you keep the form field optional, it can be used for responses to any form; and you'll need to add help text to let users know what to expect if they do not select a form.
## 3. Format the responses the trigger receives
### Question and answer fields
* Form fields or survey questions must include the same name within Zapier as that form field shown in your app's user interface.
* In a form that asks for contact information, the question/field “What's your email?” might internally use an ID like `1839dod38k01` or a generic label such as `Question 1` in your app's API. The user should also see the field's friendly name within Zapier so they'll recognize which field to use when mapping data to action steps. The raw field ID, the `key`, can still be shown beside the friendly name.
* For example, a common use case is to log responses in spreadsheets, with each answer field mapped to different columns. Showing only the key `q_1_answer` for a question is not intuitive for users. Include the label with the full question.
* Include the question number as a prefix to the label if possible, to help users find specific questions and fields.
### Multiple choice fields
* Include the question title, answer and value as separate fields where possible. Use the same label to group these together in the trigger output.
* When a multiple choice question is based on a range of values (e.g., from “not really” to “very”), it is useful to return the choice values (such as `1` to `5`) with the actual answer. This can be especially helpful for users wishing to track responses in a spreadsheet.
### Multi-select fields
* When users can select multiple responses (like a list of checkboxes) in a form or survey, it can be challenging to use this data within a trigger.
* When possible, return these responses individually by splitting each individual response to the question into its own field, with a value if it is selected by the responder and a blank value if not selected. This makes mapping Zap steps simpler because users can map all responses into one field separated by the correct delimiter, or can take action on specific responses when they are present with the user of [Filters](https://help.zapier.com/hc/en-us/articles/8496276332557-Add-conditions-to-Zaps-with-filters) or [Paths](https://zapier.com/features/paths).
* Depending on your app's API response fields, you might instead opt to return the question's selected values in a single, comma separated field. Users can then split the values themselves with Zapier's [Formatter](https://help.zapier.com/hc/en-us/articles/8496030096013-How-to-use-Formatter-Functions#using-split-text-0-3) tool, or could map the all the values together to a later step's field.
### Date fields
* Return the timestamp when the response was completed in [ISO 8601 format](/platform/publish/branding-guidelines#output-data). Also return any dates users can select in the form or survey in ISO 8601 format.
* When possible, also include a human-friendly date for the response completion and any other selected dates in the response.
### File attachments
* When users can attach files to form responses, include those in the response data as a publicly accessible URL for the file.
* You could configure Zapier to request the full file via [file dehydration](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#file-dehydration) but you'll need to then work in the [Platform CLI](/platform/quickstart/cli-tutorial).
## 4. Choose trigger type under API Configuration
### REST Hook trigger
* If your app supports webhook subscriptions that can be manipulated through a REST API, use [REST hooks](/platform/build/trigger#rest-hook-trigger) for your trigger to send new form entries to Zapier as soon as the form is filled out.
* Webhook triggers are marked as *Instant* [in the Zap Editor](https://cdn.zappy.app/6b696dfaf34664b181b6df651067cfd3.png).
* When your user has many form entries in a short space of time, webhooks make your integration more robust, preventing the possibility that a high number of new entries will exceed the page size of polling results.
* With REST hooks, Zapier won't need to repeatedly poll your API to check for new responses.
### Polling trigger
* When using a Polling trigger, and for the *Perform List* URL for REST Hook triggers, the Polling URL should return the most recent form entry for the chosen form.
* If there are no entries for the selected form, return an empty array. Zapier will then encourage the user to create a sample then re-test their trigger in the Zap Editor to finish mapping their Zap.
## 5. Handle Sample data
* Zapier requests sample results for every trigger and action when users select *Skip test* if the test API call returns no data.
* Since a form app has dynamic fields unique to each user, it's impossible to define sample data that work for every form.
* Instead, include only the common form fields that would be present for every result, such as form ID and timestamp, for the trigger's static sample data.
## 6. Test your triggers
Make Zaps with the trigger for the following criteria to ensure your app integration works as expected:
* A triggering form that already has completed entries, where you should check that your polling URL is returning the latest form entry first (reverse chronological).
* A brand new triggering form with no entries, to make sure your form sends an appropriate error when no results exists.
* A triggering form that is composed of required and optional questions, to make sure all the questions are mappable into later action steps, regardless of whether the latest response only had a few questions answered.
* A triggering form that has questions with multi select answers, where you should choose one or more options when sending a response in your app, to check that all the values come through.
* Turn on the Zaps and submit new entries to each form to check that the Zap triggers and includes the expected response.
***
*Need help? [Tell us about your problem](https://developer.zapier.com/contact) and we'll connect you with the right resource or contact support.*
# Implementing OAuth v2 authentication
Source: https://docs.zapier.com/platform/reference/implementing-oauth-tutorial
With OAuth v2 authentication, users authenticate to the Zapier integration via the app’s own site, helping them to easily connect accounts without needing to share account credentials or look up API keys.
# Scripting in converted Legacy Web Builder Integrations
Source: https://docs.zapier.com/platform/reference/legacy-scripting
This guide provides instructions on editing and maintaining existing scripting methods for legacy web builder integrations that have been converted to either the Platform UI or Platform CLI.
## Introduction
> **Note**: This guide isn't for new integrations built in Platform CLI or Platform UI. For new integrations, use the [Platform UI](/platform/quickstart/ui-tutorial) or the [Platform CLI](/platform/reference/cli-docs) to build an integration in code.
If you are creating new functionality, check maintaining your converted integration for the best way forward.
Much like [Code Mode](/platform/build/code-mode), Zapier's Web Builder Scripting was the previous way to allow you to directly manipulate the requests and responses that are exchanged between your app's API and Zapier. It continues to be supported using both the Platform UI and CLI.
## Access and edit scripting
For integrations converted to Platform UI, you can access and edit these scripting methods by:
1. Log into the [Platform UI](https://zapier.com/app/developer).
2. Select your **integration**.
3. In the *Build* section in the left sidebar, click **Advanced**.
4. Click the **Legacy Web Builder** tab.
For integrations converted to Platform CLI, you can access and edit these scripting methods in the **Scripting.js** file. Its default location in the root directory of your CLI integration.
Every converted Web Builder integration will have a root module `Zap` defined in this Scripting.js file. By default, it is a blank JavaScript object. You add to it by specifying one or more of the [available methods](/platform/reference/legacy-scripting#available-methods). Each method accepts a single variable called `bundle`, which is a JSON serializable object. The content of the bundle varies depending on the method you are implementing. The output of your method must also be a serializable object.
Below is an example of implementing a method to be a pass-through:
```javascript
var Zap = {
my_trigger_pre_poll: function(bundle) {
// your code to modify bundle.request before sent
return bundle.request;
}
}
```
**Note**: All code written in the Scripting API must adhere to [strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode), which is a subset of Javascript. Any issues with your code that violate this will be shown in the Scripting API editor with red X marks in the sidebar. The code will run in the current Node.js used for the platform - you can track this [here.](https://github.com/zapier/zapier-platform/blob/main/CHANGELOG.md)
## Available methods
There are various methods for manipulating requests Zapier makes to your API. Below is the complete list of methods you can use in scripting. You may provide any, all, or none of these methods.
### Trigger methods
Many of the trigger methods follow a naming pattern of key + method name, where key is the key given to the trigger when you created it. Below, Zapier uses the convention of `KEY` as the placeholder for the trigger's actual key. For example, if you define a trigger with the key “my\_trigger” and want to implement the pre\_poll method, you would write a method called `my_trigger_pre_poll`.
### Polling
#### `KEY_pre_poll`
Runs before the request to the polling URL can modify the request before it is sent.
```javascript
var Zap = {
KEY_pre_poll: function(bundle) {
/\*
Argument:
bundle.request.method: # "GET"
bundle.request.url:
bundle.request.auth:
bundle.request.headers:
bundle.request.params:
bundle.url_raw:
bundle.auth_fields:
bundle.trigger_fields: # the fields provided by the user during setup
bundle.zap: # info about the zap
bundle.meta: # extra runtime information you can use
The response should be bundle.request or a similar object
\*/
return {
url: bundle.request.url,
method: bundle.request.method,
auth: bundle.request.auth,
headers: bundle.request.headers,
params: bundle.request.params,
data: bundle.request.data
}; // or return bundle.request;
}
}
```
See [bundle.request](/platform/reference/legacy-scripting#prepared-request-via-bundlerequest).
> **Note**: This code is only valid for Zapier's Legacy Web Builder. It's mostly incompatible with Zapier's Platform CLI and Platform UI.
#### `KEY_post_poll`
It runs after Zapier receives a response from the polling URL. Can parse the response to format the data that enters Zapier or throw an [exception](/platform/reference/legacy-scripting/#available-exceptions). Zapier will automatically throw for status codes 4xx and 5xx after the method runs.
```javascript
var Zap = {
KEY_post_poll: function(bundle) {
/\*
Argument:
bundle.response.status_code:
bundle.response.headers:
bundle.response.content:
bundle.request:
bundle.auth_fields:
bundle.trigger_fields: # the fields provided by the user during setup
bundle.zap: # info about the zap
bundle.meta: # extra runtime information you can use
The response should be JSON serializable:
[
, # with unique 'id' key
# with unique 'id' key
]
\*/
return [];
}
}
```
> **Note**: This code is only valid for Zapier's Legacy Web Builder. It's mostly incompatible with Zapier's Platform CLI and Platform UI.
#### `KEY_poll`
It runs in place of pre\_poll and post\_poll. When you get a bundle, you are expected to make the request and return a list of results or throw an [exception](/platform/reference/legacy-scripting/#available-exceptions). Zapier will **not** throw for status codes like 4xx and 5xx automatically!
```javascript
var Zap = {
KEY_poll: function(bundle) {
/\*
Arguments:
bundle.request.method: # "GET"
bundle.request.url:
bundle.request.auth:
bundle.request.headers:
bundle.request.params:
bundle.url_raw:
bundle.auth_fields:
bundle.trigger_fields: # the fields provided by the user during setup
bundle.zap: # info about the zap
bundle.meta: # extra runtime information you can use
If you include a callback in the arguments, you can also perform async:
callback(err, response)
You must make the request yourself. The response should be JSON serializable:
[
, # with unique 'id' key
# with unique 'id' key
]
\*/
return []; // or callback(null, [])
}
}
```
Learn more about [bundle.request](/platform/reference/legacy-scripting#bundle-details).
> **Note**: This code is only valid for Zapier's Legacy Web Builder. It's mostly incompatible with Zapier's Platform CLI and Platform UI.
### Static and REST hooks
#### `KEY_catch_hook`
It runs when Zapier receive a static or subscription hook from your API and can parse the response to format the data that enters Zapier.
```javascript
var Zap = {
KEY_catch_hook: function(bundle) {
/\*
Argument:
bundle.request.method: # 'GET', 'POST', 'PATCH', 'PUT', 'DELETE'
bundle.request.headers:
bundle.request.querystring: # parse with \$.param(bundle.request.querystring)
bundle.request.content:
bundle.cleaned_request: or # our best guess at parsing
# and combining the request
# (including handling JSON & XML).
bundle.auth_fields:
bundle.trigger_fields: # the fields provided by the user during setup
bundle.zap: # info about the zap
The response should be either a JSON serializable array...
[
,
]
...or a single object:
\*/
return []; // or {}
}
}
```
> **Note**: This code is only valid for Zapier's Legacy Web Builder. It's mostly incompatible with Zapier's Platform CLI and Platform UI.
### REST hooks and notification REST hooks
#### `pre_subscribe`
It runs before Zapier subscribes.
```javascript
var Zap = {
pre_subscribe: function(bundle) {
/\*
Argument:
bundle.request.method: # "POST"
bundle.request.url:
bundle.request.auth:
bundle.request.headers:
bundle.request.params:
bundle.request.data:
bundle.auth_fields:
bundle.trigger_fields: # the data from trigger fields
bundle.target_url: # our unique Zapier url for this subscription
bundle.event: # the event being subscribed to
bundle.zap: # info about the zap
The response should be bundle.request or a similar object
\*/
return {
url: bundle.request.url,
method: bundle.request.method,
auth: bundle.request.auth,
headers: bundle.request.headers,
params: bundle.request.params,
data: bundle.request.data
}; // or return bundle.request;
}
}
```
Learn more in [bundle.request](/platform/reference/legacy-scripting#bundle-details).
> **Note**: This code is only valid for Zapier's legacy web builder, and is mostly incompatible with Platform CLI and Platform UI).
#### `post_subscribe`
It runs after Zapier subscribes. It is exclusively for storing results that are needed later for pre\_unsubscribe.
```javascript
var Zap = {
post_subscribe: function(bundle) {
/\*
Argument:
bundle.response.status_code:
bundle.response.headers:
bundle.response.content:
bundle.request:
bundle.target_url: # our unique Zapier url for this subscription
bundle.event: # the event (if any) that was subscribed to
bundle.auth_fields:
bundle.trigger_fields: # the data from trigger fields
bundle.zap: # info about the zap
The response should be JSON serializable, you'll have access to it as
subscribe_data in the unsubscribe call. Normally you'd store some state
about the hook resource you created, for example, some apps need
an ID to locate and unsubscribe from a hook.
\*/
return ""; // or {}, or []
}
}
```
> **Note**: This code is only valid for Zapier's Legacy Web Builder. It's mostly incompatible with Zapier's Platform CLI and Platform UI.
#### `pre_unsubscribe`
It runs before Zapier unsubscribes.
```javascript
var Zap = {
pre_unsubscribe: function(bundle) {
/\*
Argument:
bundle.request.method: # "POST"
bundle.request.url:
bundle.request.auth:
bundle.request.headers:
bundle.request.params:
bundle.request.data:
bundle.target_url: # our unique Zapier url for this subscription
bundle.subscribe_data # any data you returned from post_subscribe
bundle.event: # the event (if any) being unsubscribed from
bundle.auth_fields:
bundle.trigger_fields: # the data from trigger fields
bundle.zap: # info about the zap
The response should be bundle.request or a similar object
\*/
return {
url: bundle.request.url,
method: bundle.request.method,
auth: bundle.request.auth,
headers: bundle.request.headers,
params: bundle.request.params,
data: bundle.request.data
}; // or return bundle.request;
}
}
```
Learn more in [bundle.request](/platform/reference/legacy-scripting#bundle-details).
> **Note**: This code is only valid for Zapier's Legacy Web Builder. It's mostly incompatible with Zapier's Platform CLI and Platform UI.
### Notification REST hooks
#### `KEY_pre_hook`
It runs before the consuming call.
```javascript
var Zap = {
KEY_pre_hook: function(bundle) {
/\*
Argument:
bundle.request.method:
bundle.request.headers:
bundle.request.querystring: # parse using \$.param(bundle.request.querystring)
bundle.request.content:
bundle.auth_fields:
bundle.trigger_fields: # the fields provided by the user during setup
bundle.zap: # info about the zap
The response should be bundle.request or a similar object
\*/
return {
url: bundle.request.url,
method: bundle.request.method,
auth: bundle.request.auth,
headers: bundle.request.headers,
params: bundle.request.params,
data: bundle.request.data
}; // or return bundle.request;
}
}
```
Learn more in [bundle.request](/platform/reference/legacy-scripting#bundle-details).
> **Note**: This code is only valid for Zapier's Legacy Web Builder. It's mostly incompatible with Zapier's Platform CLI and Platform UI.
#### `KEY_post_hook`
It runs after Zapier receive a response from the consuming call and can parse the response to format the data that enters Zapier or throw an [exception](/platform/reference/legacy-scripting/#available-exceptions). Zapier will automatically throw for status codes 4xx and 5xx after the method runs.
```javascript
var Zap = {
KEY_post_hook: function(bundle) {
/\*
Argument:
bundle.response.status_code:
bundle.response.headers:
bundle.response.content:
bundle.request:
bundle.auth_fields:
bundle.trigger_fields: # the fields provided by the user during setup
bundle.zap: # info about the zap
The response should be JSON serializable:
[
,
]
\*/
return [];
}
}
```
> **Note**: This code is only valid for Zapier's Legacy Web Builder. It's mostly incompatible with Zapier's Platform CLI and Platform UI.
### Available to all triggers
#### `KEY_pre_custom_trigger_fields`
It runs before the request to the custom field URL (if provided).
> Note: Although this method does not end with `result_fields` like there are for [actions](#key_pre_custom_action_fields) and [searches](#key_pre_custom_search_fields) it does in fact define custom fields and labels for the **result** (sample) of the trigger and not for its **Edit Template** step in the Zap editor.
```javascript
var Zap = {
KEY_pre_custom_trigger_fields: function(bundle) {
/\*
Argument:
bundle.request.method: # "GET"
bundle.request.url:
bundle.request.auth:
bundle.request.headers:
bundle.request.params:
bundle.url_raw:
bundle.auth_fields:
bundle.trigger_fields: # the fields provided by the user during setup
bundle.zap: # info about the zap
The response should be bundle.request or a similar object
\*/
return {
url: bundle.request.url,
method: bundle.request.method,
auth: bundle.request.auth,
headers: bundle.request.headers,
params: bundle.request.params,
data: bundle.request.data
}; // or return bundle.request;
}
}
```
Learn more in [bundle.request](/platform/reference/legacy-scripting#bundle-details).
> **Note**: This code is only valid for Zapier's Legacy Web Builder. It's mostly incompatible with Zapier's Platform CLI and Platform UI.
#### `KEY_post_custom_trigger_fields`
Runs after the response for custom fields is received. Can parse the response to format the data that enters Zapier or throw an [exception](/platform/reference/legacy-scripting/#available-exceptions). Zapier will throw for status codes 4xx and 5xx after the method runs automatically.
> Note: Although this method does not end with `result_fields` like there are for [actions](#key_pre_custom_action_fields) and [searches](#key_pre_custom_search_fields) it does in fact define custom fields and labels for the **result** (sample) of the trigger and not for its **Edit Template** step in the Zap Editor.
```javascript
var Zap = {
KEY_post_custom_trigger_fields: function(bundle) {
/\*
Argument:
bundle.response.status_code:
bundle.response.headers:
bundle.response.content:
bundle.request:
bundle.url_raw:
bundle.auth_fields:
bundle.trigger_fields: # the fields provided by the user during setup
bundle.zap: # info about the zap
The response should be JSON serializable:
[
# `type` can be unicode, int, bool
# `key` should be unique and match a key found in the JSON representation Zapier receive from your API
# `label` is a human-readable name Zapier can give this field in the UI
{'type': , 'key': , 'label': }
]
\*/
return [];
}
}
```
> **Note**: This code is only valid for Zapier's Legacy Web Builder. It's mostly incompatible with Zapier's Platform CLI and Platform UI.
## Action Methods
Action methods follow a naming pattern of key + method name, where key is the key given to the action when you created it. Below, Zapier use the convention of `KEY` as the placeholder for the action's actual key. For example, if you define an action with the key “my\_action” and you want to implement the pre\_write method, you would write a method called `my_action_pre_write`.
### `KEY_pre_write`
Runs before the request to the action URL, can modify the request before it is sent.
```javascript
var Zap = {
KEY_pre_write: function(bundle) {
/\*
Argument:
bundle.request.method: # "POST"
bundle.request.url:
bundle.request.auth:
bundle.request.headers:
bundle.request.params:
bundle.request.data:
bundle.request.files:
bundle.url_raw:
bundle.auth_fields:
bundle.action_fields: # pruned and replaced users' fields
bundle.action_fields_full: # all replaced users' fields
bundle.action_fields_raw: # before Zapier replace users' variables
bundle.zap: # info about the zap
The response should be bundle.request or a similar object
\*/
return {
url: bundle.request.url,
method: bundle.request.method,
auth: bundle.request.auth,
headers: bundle.request.headers,
params: bundle.request.params,
data: bundle.request.data
}; // or return bundle.request;
}
}
```
Learn more about [bundle.request](/platform/reference/legacy-scripting#bundle-details).
> **Note**: This code is only valid for Zapier's Legacy Web Builder. It's mostly incompatible with Zapier's Platform CLI and Platform UI.
### `KEY_post_write`
Runs after Zapier receive a response from the action endpoint, can modify the response or throw an [exception](/platform/reference/legacy-scripting/#available-exceptions). Zapier will throw for status codes 4xx and 5xx after the method runs automatically. *Note:* If the action occurs as part of a search-or-create Zap, the output of this method is *not* exactly what the user sees. In that case, the action will be followed up with a request to fetch the written record, and Zapier will present the user with the output from that follow-up request. If you need to modify the returned data in that scenario, use `_post_read_resource`.
```javascript
var Zap = {
KEY_post_write: function(bundle) {
/\*
Argument:
bundle.response.status_code:
bundle.response.headers:
bundle.response.content:
bundle.request:
bundle.auth_fields:
bundle.action_fields: # pruned and replaced users' fields
bundle.action_fields_full: # all replaced users' fields
bundle.action_fields_raw: # before Zapier replace users' variables
bundle.zap: # info about the zap
The response will be used to give the user more fields to use
in the next step of the Zap. Please return a JSON serializable object.
return ;
\*/
}
}
```
> **Note**: This code is only valid for Zapier's Legacy Web Builder. It's mostly incompatible with Zapier's Platform CLI and Platform UI.
### `KEY_write`
Runs in place of pre\_write and post\_write. You get a bundle and are expected to make the request and return the appropriate response or throw an [exception](/platform/reference/legacy-scripting/#available-exceptions). Zapier will **not** throw for status codes like 4xx and 5xx automatically! \_Note:\_ If the action occurs as part of a search-or-create Zap, the output of this method is *not* exactly what the user sees. In that case, the action will be followed up with a request to fetch the written record, and Zapier will present the user with the output from that follow-up request. If you need to modify the returned data in that scenario, use `_post_read_resource`.
```javascript
var Zap = {
KEY_write: function(bundle, [callback]) {
/\*
Arguments:
bundle.request.method: # "POST"
bundle.request.url:
bundle.request.auth:
bundle.request.headers:
bundle.request.params:
bundle.request.data:
bundle.request.files:
bundle.url_raw:
bundle.auth_fields:
bundle.action_fields: # pruned and replaced users' fields
bundle.action_fields_full: # all replaced users' fields
bundle.action_fields_raw: # before Zapier replace users' variables
bundle.zap: # info about the zap
If you include a callback in the arguments, you can also perform async:
callback(err, response)
The response will be used to give the user more fields to use
in the next step of the Zap. Please return a JSON serializable object.
return ;
\*/
// your code to modify bundle.request before sent
var response = z.request(bundle.request);
return z.JSON.parse(response.content);
}
}
```
Learn more about [bundle.request](/platform/reference/legacy-scripting#bundle-details).
> **Note**: This code is only valid for Zapier's Legacy Web Builder. It's mostly incompatible with Zapier's Platform CLI and Platform UI.
### `KEY_pre_custom_action_fields`
Runs before the request to the custom field URL (if provided).
```javascript
var Zap = {
KEY_pre_custom_action_fields: function(bundle) {
/\*
Argument:
bundle.request.method: # "GET"
bundle.request.url:
bundle.request.auth:
bundle.request.headers:
bundle.request.params:
bundle.url_raw:
bundle.auth_fields:
bundle.action_fields: # the raw action fields (if applicable)
bundle.zap: # info about the zap (details below)
The response should be bundle.request or a similar object
\*/
return {
url: bundle.request.url,
method: bundle.request.method,
auth: bundle.request.auth,
headers: bundle.request.headers,
params: bundle.request.params,
data: bundle.request.data
}; // or return bundle.request;
}
}
```
Learn more about [bundle.request](/platform/reference/legacy-scripting#bundle-details).
> **Note**: This code is only valid for Zapier's Legacy Web Builder. It's mostly incompatible with Zapier's Platform CLI and Platform UI.
### `KEY_post_custom_action_fields`
Runs after the response for custom fields is received. Can parse the response to format the data that enters Zapier or throw an [exception](/platform/reference/legacy-scripting/#available-exceptions). Zapier will throw for status codes 4xx and 5xx after the method runs automatically.
```javascript
var Zap = {
KEY_post_custom_action_fields: function(bundle) {
/\*
Argument:
bundle.response.status_code:
bundle.response.headers:
bundle.response.content:
bundle.request:
bundle.url_raw:
bundle.auth_fields:
bundle.action_fields: # the fields provided by the user during setup
bundle.zap: # info about the zap
The response should be JSON serializable:
[
# `type` can be unicode, int, bool
# `key` should be unique, and will be the "key" in "key: value" in the POST
# `help_text` and `label` are also available
{'type': , 'key': }
]
\*/
return []; // return fields in the order you want them displayed in the UI. They'll be appended after the regular action fields
}
}
```
> **Note**: This code is only valid for Zapier's Legacy Web Builder. It's mostly incompatible with Zapier's Platform CLI and Platform UI.
### `KEY_custom_action_fields`
Allows you to completely take over the handling of retrieving and processing field metadata for custom action fields. Pre- and Post- methods will not be called if you've implemented this method. This method will be passed a bundle and must return an array of custom field metadata. If a request to an endpoint fails, you will need to throw an exception - the platform will not do it automatically.
```javascript
var Zap = {KEY_custom_action_fields: function(bundle) {
/\*
Argument:
bundle.request.method: # GET
bundle.request.url: # ""
bundle.request.auth:
bundle.request.headers:
bundle.request.params:
bundle.url_raw: # ""
bundle.auth_fields:
bundle.action_fields: # the raw action fields (if applicable)
bundle.zap: # info about the zap
The response should be JSON serializable:
[
# "type": "unicode",
# "key": "json_key", // the field "name", will be used to construct a label if none is provided
# "required": false, // whether this field must be filled out. defaults to true
# "label": "Pretty Label", // optional
# "help_text": "Helps to explain things to users.", // optional
# "choices": { // optional
"raw": "label"
} // can also be a flat array if raw is the label
{'type': , 'key': }
]
*/
return []; // return fields in the order you want them displayed in the UI. They'll be appended after the regular action fields
}
}
```
Learn more about [bundle.request](/platform/reference/legacy-scripting#bundle-details).
> **Note**: This code is only valid for Zapier's Legacy Web Builder. It's mostly incompatible with Zapier's Platform CLI and Platform UI.
### `KEY_custom_action_result_fields`
It allows you to completely take over the handling of retrieving and processing field metadata for custom fields when users are working with *results* of your action in the Zap editor. Pre- and Post- methods will not be called if you've implemented this method. This method will be passed a bundle and must return an array of custom field metadata. If a request to an endpoint fails, you will need to throw an exception - the platform will not do it automatically.
```javascript
var Zap = {KEY_custom_action_result_fields: function(bundle) {
/\*
Argument:
bundle.response.status_code:
bundle.response.headers:
bundle.response.content:
bundle.request:
bundle.url_raw:
bundle.auth_fields:
bundle.action_fields: # the raw action fields (if applicable)
bundle.zap: # info about the zap
The response should be JSON serializable:
[
# `type` can be unicode, int, bool
# `key` should be unique, and will be the "key" in "key: value" in the response content
# `label` is also available
{'type': , 'key': , 'label': }
]
\*/
return []; // return fields in the order you want them displayed in the UI. They'll be appended after the regular action fields
}
}
```
> **Note**: This code is only valid for Zapier's Legacy Web Builder. It's mostly incompatible with Zapier's Platform CLI and Platform UI.
### `KEY_pre_custom_action_result_fields`
Runs before the request to the custom response fields URL (if provided).
```javascript
var Zap = {
KEY_pre_custom_action_result_fields: function(bundle) {
/\*
Argument:
bundle.request.method: # "GET"
bundle.request.url:
bundle.request.auth:
bundle.request.headers:
bundle.request.params:
bundle.url_raw:
bundle.auth_fields:
bundle.action_fields: # the raw action fields (if applicable)
bundle.zap: # info about the zap (details below)
The response should be bundle.request or a similar object
\*/
return {
url: bundle.request.url,
method: bundle.request.method,
auth: bundle.request.auth,
headers: bundle.request.headers,
params: bundle.request.params,
data: bundle.request.data
}; // or return bundle.request;
}
}
```
Learn more about [bundle.request](/platform/reference/legacy-scripting#bundle-details).
> **Note**: This code is only valid for Zapier's Legacy Web Builder. It's mostly incompatible with Zapier's Platform CLI and Platform UI.
### `KEY_post_custom_action_result_fields`
Runs after the response for custom response fields is received. Can parse the response to format the data that enters Zapier or throw an exception [exception](/platform/reference/legacy-scripting/#available-exceptions). Zapier will throw for status codes 4xx and 5xx after the method runs automatically.
```javascript
var Zap = {
KEY_post_custom_action_result_fields: function(bundle) {
/\*
Argument:
bundle.response.status_code:
bundle.response.headers:
bundle.response.content:
bundle.request:
bundle.url_raw:
bundle.auth_fields:
bundle.action_fields: # the raw action fields (if applicable)
bundle.zap: # info about the zap
The response should be JSON serializable:
[
# `type` can be unicode, int, bool
# `key` should be unique, and will be the "key" in "key: value" in the response content
# `label` is also available
{'type': , 'key': , 'label': }
]
\*/
return []; // return fields in the order you want them displayed in the UI. They'll be appended after the regular action fields
}
}
```
## Search Methods
Search methods follow a naming pattern of key + method name, where key is the key given to the search when you created it. Below, Zapier use the convention of `KEY` as the placeholder for the search's actual key. For example, if you define an search with the key “my\_search” and you want to implement the pre\_search method, you would write a method called `my_search_pre_search`.
### `KEY_pre_search`
Runs before the request to the search URL, can modify the request before it is sent.
```javascript
var Zap = {
KEY_pre_search: function(bundle) {
/\*
Argument:
bundle.request.method: # "GET"
bundle.request.url:
bundle.request.auth:
bundle.request.headers:
bundle.request.params:
bundle.url_raw:
bundle.auth_fields:
bundle.search_fields: # pruned and replaced users' fields
bundle.zap: # info about the zap
The response should be bundle.request or a similar object
\*/
return {
url: bundle.request.url,
method: bundle.request.method,
auth: bundle.request.auth,
headers: bundle.request.headers,
params: bundle.request.params,
data: bundle.request.data
}; // or return bundle.request;
}
}
```
Learn more about [bundle.request](/platform/reference/legacy-scripting#bundle-details).
> **Note**: This code is only valid for Zapier's Legacy Web Builder. It's mostly incompatible with Zapier's Platform CLI and Platform UI.
### `KEY_post_search`
Runs after Zapier receive a response from the search endpoint, can modify the response or throw an [exception](/platform/reference/legacy-scripting/#available-exceptions). Zapier will throw for status codes 4xx and 5xx after the method runs automatically. *Note:* The output of the method is *not* exactly what the user sees. Zapier follow searches up with requests for the individual resources and present the user with the output from those follow-up requests. If you wish to modify the number (or ordering) of the search results, use `_post_search`. If you wish to modify the data the user sees, use `_post_read_resource`. One other thing to be aware of is that searches must return an *array* of objects, so if your search endpoint returns a single object, you can use this method to wrap your object in an array.
> Note we'll only use the first object in the array for now, so if you can add optional fields to help narrow the search down, it's a great idea.
```javascript
var Zap = {
KEY_post_search: function(bundle) {
/\*
Argument:
bundle.response.status_code:
bundle.response.headers: