# Get Action Details post /api/v2/apps/{app}/actions/{action}/ Get details of a specific action, including its needs, gives, and a sample of the action. # Get Prefill Choices post /api/v2/apps/{app}/choices/{prefill}/ Get prefill choices for an app's prefill. # Search Actions get /api/v2/apps/{app}/actions/ Search for Zapier actions by app, ordered by relevancy. # Create AI Action post /api/v2/ai-actions/ Create a new AI Action that can be executed by the user later. # Delete AI Action delete /api/v2/ai-actions/{ai_action_id}/ Delete an AI Action. Returns `true` if the action was deleted, `false` if it was not found. # Get AI Action get /api/v2/ai-actions/{ai_action_id}/ Get the details of a specific AI Action. # List AI Actions get /api/v2/ai-actions/ List all the current actions for the current user. # Update AI Action put /api/v2/ai-actions/{ai_action_id}/ Update an existing AI Action. # Get App Details get /api/v2/apps/{app}/ # List Authentications For App get /api/v2/apps/{app}/auths/ Get list of Zapier authentications associated with the requesting user and account. # Search Apps get /api/v2/apps/search/ # Check User Auth get /api/v2/auth/check/ Test that the API and auth are working. # Get Account List get /api/v2/auth/accounts/ Get a list of Zapier accounts for the current user. # Get Oauth Login Link get /api/v2/auth/oauth-login-link/ This will create a link that can be used for "quick account creation" followed by OAuth login for a user. When going to this link, if the provided email already has a Zapier account, the user will be asked to log in. If the email does not have a Zapier account, the user will be asked to create an account with the provided email and name. Upon creating an account or logging in, the user will be taken to The user will get a Zapier account, be brought to AI Actions where they will see the OAuth consent screen, and then will be brought back to your site with an OAuth `code` that can be used with `https://actions.zapier.com/oauth/token/` with the following data in the body with `Content-Type: application/x-www-form-urlencoded`: - client_id: Your AI Actions OAuth client ID - grant_type: `authorization_code` - code_verifier: The verifier stored for your user when generating the login URL - redirect_uri: The same URL you used for the `redirect_uri` in the previous step. - code: The code in the query parameters of the URL that the user was redirected to. # Get User Login Link get /api/v2/auth/login-link/ This will create a link that can be used for "quick account creation" for a user. When going to this link, if the provided email already has a Zapier account, the user will be asked to log in. If the email does not have a Zapier account, the user will be asked to create an account with the provided email and name. Upon creating an account or logging in, the user will be taken to the `redirect_to` URL. A suggested flow for this is: - Check if you have an AI Actions OAuth token for a user - If you do not, send the user to a page on your site for initiating PKCE OAuth flow, storing the `code_verifier` for them securely. - Use this endpoint, with a `redirect_to` of `https://actions.zapier.com/oauth/authorize/` with the following query parameters: - client_id: Your AI Actions OAuth client ID - scope: `openid nla:exposed_actions:execute` - response_type: `code` - redirect_uri: The URL on your site that will handle the OAuth callback, must be in the list of allowed redirect URIs for your AI Actions OAuth client. - code_challenge: The SHA256 hash of the `code_verifier` from the previous step. - code_challenge_method: `S256` The user will get a Zapier account, be brought to AI Actions where they will see the OAuth consent screen, and then will be brought back to your site with an OAuth `code` that can be used with `https://actions.zapier.com/oauth/token/` with the following data in the body with `Content-Type: application/x-www-form-urlencoded`: - client_id: Your AI Actions OAuth client ID - grant_type: `authorization_code` - code_verifier: The verifier stored for your user when generating the login URL - redirect_uri: The same URL you used for the `redirect_uri` in the previous step. - code: The code in the query parameters of the URL that the user was redirected to. # Execute Stateless AI Action post /api/v2/execute/ # Execute Stored AI Action post /api/v2/ai-actions/{ai_action_id}/execute/ Given an action ID and instructions, this will execute the action and return the results. # Preview Stored AI Action post /api/v2/ai-actions/{ai_action_id}/preview/ # Rate Execution Log post /api/v2/execute/log/{execution_log_id}/rate/ Rate a specific execution log given feedback from the user. Rating should either be `-1` (bad, thumbs down), `0` (neutral, the default), or `1` (good, thumbs up). You can also provide plain text feedback provided by the user. Supplied rating/feedback are patched onto execution log, so you can progressively call this endpoint. # App Health Check get /api/v2/health/ Check that the app is up and running. # Guess Actions post /api/v2/guess-actions/ # Shrink Result post /api/v2/shrink-result/ **WARNING: This endpoint is not officially supported, and is subject to be changed or removed at any time.** Shrinks the given result payload to git into a specified token budget. This tries its best to keep around more important values and truncate less important ones. The intent of this endpoint is that after executing an AI Action, you can pass the result into this to get a smaller result that can be passed in to LLMs without hitting the token limit. # API Key # API Logs # OpenAPI Specification # Submit an issue # Join our Community # Zapier account list get /api/v2/auth/accounts/ Get a list of Zapier accounts for the current user. Each user can have multiple Zapier accounts. This endpoint returns a list of all the accounts that the user has access to. When interacting with the AI Actions API, you will need to provide a specific account ID to most endpoints. # Get action details and needs post /api/v2/apps/{app}/actions/{action}/ Get details of a specific action, including its needs, gives, and a sample of the action. "Needs" are the values that need to be provided when the action is run. Needs that are not provided will be guessed by the AI when the action is run. "Gives" are the values that the action returns when it is run. "Sample" is a sample of what the action returns when it is run. When you [Run a stateless action](/ai-actions/how-tos/stateless/run-stateless-action), "needs" are provided to the endpoint. For each need, you can either have AI guess a value for it or you can ask the user to provide a specific value. ## Custom fields The list of needs that this returns can change based on the `params` provided in the request body. As such, this endpoint may need to be hit multiple times as needs are chosen by the user. This endpoint needs to be hit again whenever the selected value for a need changes and *any of the following* are true: * The changed need has `alters_custom_fields` set to `true` * The changed need is in the `depends_on` array of another need * The changed need has `custom_field` set to `true` As an example, when using the `GoogleSheetsV2API` API with the `add_row` action, the first time you get the action you will get back these `action_needs`: ```json { "action_needs": [ { "key": "spreadsheet", "label": "Spreadsheet", "prefill": "spreadsheet.id.title", "custom_field": false, "depends_on": [], "alters_custom_fields": true }, { "key": "worksheet", "label": "Worksheet", "prefill": "worksheet.id.title", "custom_field": false, "depends_on": ["spreadsheet"], "alters_custom_fields": true } ] } ``` In order to get the column names of the spreadsheet, you'll have to get the prefill choices. See [Get Prefill Choices](/ai-actions/how-tos/action-info/prefill-choices) for more information. In this example scenario, after getting values for the `spreadsheet` and `worksheet` prefills, another call can be made to this endpoint. This time, in the body of the `POST`, we can include the selected values: ```json { "params": { "spreadsheet": "SOME_SPREADSHEET_ID", // this is the ID of a spreadsheet in Google Sheets "worksheet": "0" // the first worksheet in the spreadsheet } } ``` Now, the action details will include the columns from the spreadsheet as custom fields: ```json { "action_details": [ // ... same results as above, in addition to... { "key": "COL$A", "label": "My first column", "prefill": null, "custom_field": true, "depends_on": [], "alters_custom_fields": null }, { "key": "COL$B", "label": "My second column", "prefill": null, "custom_field": true, "depends_on": [], "alters_custom_fields": null }, { "key": "COL$C", "label": "My third column", "prefill": null, "custom_field": true, "depends_on": [], "alters_custom_fields": null } ] } ``` ## Choices If the need has a `choices` array, then the value being chosen should come from that list. Often, you will see this with `boolean` fields. For example, the `SlackAPI` API's `direct_message` action contains the following need (irrelevant fields removed): ```json { "key": "as_bot", "type": "boolean", "label": "Send as a bot?", "choices": [ { "key": "no", "label": "No" }, { "key": "yes", "label": "Yes" } ], "default": "yes", "format": "SELECT" } ``` ## Other field types See [Field definitions and types](/platform/build/field-definitions) in the Zapier Platform documentation for details on the other types of fields that a need can have. # Choose authentication get /api/v2/apps/{app}/auths/ Get list of Zapier authentications associated with the requesting user and account. Authentications for each app can be managed [in your Zapier account](https://zapier.com/app/connections). # Find an action get /api/v2/apps/{app}/actions/ Search for Zapier actions by app, ordered by relevancy. # Find an app get /api/v2/apps/search/ # Introduction When using AI Actions, you will first have to build up information about the action that you want to run. ## When do I need to gather action information? See [Stored vs. Stateless Actions](/ai-actions/how-tos/stateless-vs-stored) for more information. You do **not** need to gather this information if: * You're running a **stored action** that is configured in the AI Actions UI You **do** need to gather this information if: * You're running a **stateless action** * You're setting up a new stored action using the stored action management API ## Gathering action information Each action lives under an app, for example Google Sheets or Slack. You first need to choose which app you will want to use to run an action. See [Find an app](/ai-actions/how-tos/action-info/find-app) for more details. Once you know the app you want to use, you can choose which action you want to run for that app. See [Find an action](/ai-actions/how-tos/action-info/find-action) for more details. Every app has authentications that are configured in Zapier for each user. To run an action, you need to know which Zapier account and app authentication that you want to run the action with. See [Choose authentication](/ai-actions/how-tos/action-info/choose-auth) for more details. Each action has a number of "needs" that can be used to decide what values to run the action with. See [Get action details and needs](/ai-actions/how-tos/action-info/action-details) for more details. Some of these needs are have a `prefill` key, which means that they provide a list of values that can be chosen from. See [Get prefill choices](/ai-actions/how-tos/action-info/prefill-choices) for more details. **You don't have to get a value for every need!** When running an action, you can have the AI guess values based on instructions. Once you have all of the details you need, you can either run the action as a stateless action, or save the details for later. See [Stored vs Stateless Actions](/ai-actions/how-tos/stateless-vs-stored) for more information. # Get prefill choices post /api/v2/apps/{app}/choices/{prefill}/ Get prefill choices for an app's prefill. If a need that comes back from the [Get Action Details](/ai-actions/how-tos/action-info/action-details) endpoint has a `prefill` key, then this endpoint can be used to get the choices for that prefill. ## Dependent needs If a need has any values in its `depends_on` array, the values for each of the needs in `depends_on` *must* be included in the `params` in the body of the `POST` to get prefill choices. As an example, the `action_needs` list for the `add_row` action for the `GoogleSheetsV2API` app from [Get action details and needs](/ai-actions/how-tos/action-info/action-details) includes a `spreadsheet` and a `worksheet` need: ```json { "action_needs": [ { "key": "spreadsheet", "label": "Spreadsheet", "prefill": "spreadsheet.id.title", "depends_on": [] }, { "key": "worksheet", "label": "Worksheet", "prefill": "worksheet.id.title", "depends_on": ["spreadsheet"] } ] } ``` This means that, in order to get the `worksheet.id.title` prefill choices, you need to include a `spreadsheet` value in the request to this endpoint: ```json { "params": { "spreadsheet": "SOME_SPREADHSEET_ID" } } ``` `SOME_SPREADHSEET_ID` would have come from a call to get prefill choices for the `spreadsheet.id.title` value. ## Caching By default, responses from this endpoint for a given `app`, `prefill`, `params`, and user will be cached for 24 hours. When this endpoint is first hit, a background job is started that will paginate through all of the available choices. While this background job is running, the results from this endpoint will return with `"is_loading": true`. If `is_loading` is `true`, then the endpoint should be polled every \~1 second until `is_loading` is `false`, at which point all of the available results are returned. The time that the cache was last updated is returned with `last_refresh_seconds_ago`. To force a refresh of the cache, the `force_refresh` query parameter can be set to `true`. `force_refresh` should only be used when the choices are expected to have changed, and should only be used with a single request. Repeated reqeusts with `force_refresh` set to `true` will cause results to continuously load. # Authentication get /api/v2/auth/check/ Test that the API and auth are working. # Introduction There are two methods that can be used to authenticate with `@zapier/ai-actions`: * [API Key](#api-key): If you plan on only using the AI Actions client to interact with AI Actions on your behalf * [OAuth](#oauth): If you plan on creating an OAuth app to allow users to interact with AI Actions on their behalf If you plan on using the interactive playground available in this documentation, then an API key must be user. ## API Key Follow the steps below to create your API key: 1. [Log in](https://actions.zapier.com/custom/start/) or [sign up](https://zapier.com/sign-up) to Zapier. 2. [Connect](https://actions.zapier.com/custom/actions/) your Zapier account to the `custom` integration app. 3. Your API key can be retrieved from the [Credentials page](https://actions.zapier.com/credentials/). **Treat your API key like a password.** It can be used to run your AI Actions. For example: if you set up a "Gmail: Find email" action, anyone with your API key can read all your email. ## OAuth ### Creating an OAuth app Click here to create a new OAuth app to use for authenticating with AI Actions. In order to work with the `@zapier/ai-actions` API client, **your app must have "Public Client" checked.** ### Authenticating with OAuth If you're using JavaScript/TypeScript, you can use the `@zapier/ai-actions` library to handle authentication for you! [See the `@zapier/ai-actions` documentation here](/ai-actions/libraries/nodejs/authentication#getting-an-oauth-token) ### Getting a token Your OAuth client can be used with the [PKCE flow](https://www.oauth.com/playground/authorization-code-with-pkce.html) to authenticate with AI Actions using a `Bearer` token. To begin this process, you first need to generate a code verifier and a code challenge. Here is some sample code in TypeScript to do this: ```ts /* * https://nodejs.org/api/crypto.html#cryptogetrandomvaluestypedarray * * Store the verifier securely, as it will be needed later * * @returns Verifier to use when getting a token */ const generateVerifier = () => { const array = new Uint32Array(28); crypto.getRandomValues(array); return Array.from(array, (item) => `0${item.toString(16)}`.slice(-2)).join( "" ); }; /** Base64 URL encode a buffer */ const base64URLEncode = (buffer: ArrayBuffer) => { const uint8Array = new Uint8Array(buffer); const base64String = btoa(String.fromCharCode(...uint8Array)); return base64String .replace(/\+/g, "-") .replace(/\//g, "_") .replace(/=+$/, ""); }; /** * @param verifier Verifier from `generateVerifier` * @returns Base64 URL encoded SHA-256 hash of the verifier */ const generateCodeChallenge = async (verifier: string) => { const encoder = new TextEncoder(); const data = encoder.encode(verifier); const hashBuffer = await crypto.subtle.digest("SHA-256", data); return base64URLEncode(hashBuffer); }; ``` Make sure to store the verifier securely! It will be needed when returning to your site after authenticating with AI Actions You can then send the user to AI Actions to see your OAuth consent screen: ``` https://actions.zapier.com/oauth/authorize? client_id=YOUR_CLIENT_ID& redirect_uri=YOUR_REDIRECT_URI& scope=openid%20nla%3Aexposed_actions%3Aexecute& response_type=code& code_challenge=YOUR_CODE_CHALLENGE& code_challenge_method=S256 ``` After the user has authorized your app, they will be redirected to the `redirect_uri` you provided with a `code` query parameter. You can then exchange this code for a token, using the `verifier` that you generated previously: ```sh curl -X POST "https://actions.zapier.com/oauth/token/" \ -H "Content-Type: application/x-www-form-urlencoded" \ --data-urlencode "client_id=YOUR_CLIENT_ID" \ --data-urlencode "grant_type=authorization_code" \ --data-urlencode "code_verifier=YOUR_VERIFIER" \ --data-urlencode "redirect_uri=YOUR_REDIRECT_URI" \ --data-urlencode "code=YOUR_CODE" ``` This will return the following JSON: ```ts interface OAuthAccessToken { /** JWT with user info */ id_token: string; /** Token that can be used with the `Authorization: Bearer ...` header */ access_token: string; /** Token that can be used to get a new access token */ refresh_token: string; /** Number of seconds until the token expires */ expires_in: number; token_type: "Bearer"; scope: "openid nla:exposed_actions:execute"; } ``` The `access_token` can then be used to make API calls to AI Actions: ```sh curl -X GET "https://actions.zapier.com/api/v2/auth/check" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` ### Quick account creation Since your users may not already have a Zapier account, we offer a quick account creation flow that allows users to create a Zapier account and connect their account to your app in one step. To use this flow, first generate the `/oauth/authorize` URL as outlined above. Then, get the account creation URL for your OAuth client: ```sh https://actions.zapier.com/api/v2/auth/login-link/? redirect_uri=OAUTH_AUTHORIZE_URL& sign_up_first_name=USER_FIRST_NAME& sign_up_last_name=USER_LAST_NAME& sign_up_email=USER_EMAIL ``` This will return the following JSON: ```ts { "login_link": "https://zapier.com/....." } ``` When you send a user to the provided `login_link`, they will go through a quick Zapier account creation flow. If the provided email address is already associated with a Zapier account, they will be asked to log in. Users will receive a follow-up email from Zapier to confirm their email address and to let them set a password for the account. The user will then see the AI Actions OAuth consent screen and be redirected back to your `redirect_uri` with a `code` query parameter, which can be exchanged for an access token as outlined above. ### Refreshing tokens After `expires_in` seconds, the `access_token` will expire. To get a new token, you can use the `refresh_token` that was returned when you got the original token: ```sh curl -X POST "https://actions.zapier.com/oauth/token/" \ -H "Content-Type: application/x-www-form-urlencoded" \ --data-urlencode "client_id=YOUR_CLIENT_ID" \ --data-urlencode "grant_type=refresh_token" \ --data-urlencode "refresh_token=YOUR_REFRESH_TOKEN" ``` This will return a new OAuth token that can be used in an `Authorization: Bearer ...` header. # Stored Vs. Stateless Actions When using the AI Actions API, there are two ways that actions can be run: stored and stateless. ## Stored Actions With stored actions, you let us handle storing all of the details about an action. You will only need to provide the user instructions and parameter hints when running the action. Stored actions are configured ahead of time, either using the AI Actions UI or the provided management endpoints.
Only user instructions and parameter hints are needed when running them.
A `@zapier/ai-actions-react` package is available to make it easy to interact with stored actions from a React application. ## Stateless Actions With stateless actions, you provide all of the necessary parameters at runtime. This means you will have to store action details yourself or generate the action every time you want to run it. Stateless actions are run by providing all the necessary parameters at runtime.
This gives you greater control over how actions are run.
# Stateless actions introduction When running a stateless action, all of the parameters that are needed for it to run are provided at runtime. See [Gathering Action Information](/ai-actions/how-tos/action-info/introduction) for details on how to build up the needed values that are required See [Run a Stateless Action](/ai-actions/how-tos/stateless/run-stateless-action) for information on actually running the action. # Run a Stateless Action post /api/v2/execute/ See `params_constraints` in the documentation below for details on how to tell the AI which values to use and which to guess when running the action. See [Get action details and needs](/ai-actions/how-tos/action-info/action-details) for how to discover the needs for an action. # Configure stored actions in the AI Actions UI *Planned improvements to stored actions*
While stored actions can only currently be configured on the AI Actions domain, work is planned to provide APIs and components that allow you to embed action configuration in your own UI.
Actions can be configured by you at a specific URL or with our quick configuration popup. The setup URL is the same for everyone: `https://actions.zapier.com//start/` You'd typically include a button or link somewhere to open the setup window. Here's an example of how you might do that: ```javascript var actions = window.open('https://actions.zapier.com//start', 'actions', 'width=650,height=700'); ``` # Stored actions introduction Running a stored action involves setting up the action in the AI Actions UI and then running it by its ID. This is done in the following steps: Actions need to be configured by a user before they can be used. There are two ways to set up stored actions: 1. Using the AI Actions website- see [Configure stored actions](/ai-actions/how-tos/stored/action-configuration) for more details. 2. Using the AI Action management API provided under [Manage stored actions](/ai-actions/how-tos/stored/manage/create-action). After actions are set up, they can be provided as tools to an LLM. See [List stored Actions](/ai-actions/how-tos/stored/list-actions) for more details. The LLM can then decide which action it wants to run. See [Run a stored action](/ai-actions/how-tos/stored/run-stored-action) for more details. # List stored Actions get /api/v2/ai-actions/ List all the current actions for the current user. These actions can then be provided as tools to an LLM, which can decide what parameters to use when running the action. See [Run a stored action](/ai-actions/how-tos/stored/run-stored-action) for details on running an action. # Create stored action post /api/v2/ai-actions/ Create a new AI Action that can be executed by the user later. # Delete stored action delete /api/v2/ai-actions/{ai_action_id}/ Delete an AI Action. Returns `true` if the action was deleted, `false` if it was not found. # Get stored action get /api/v2/ai-actions/{ai_action_id}/ Get the details of a specific AI Action. See [Run a stored action](/ai-actions/how-tos/stored/run-stored-action) for details on running an action. # Update stored action put /api/v2/ai-actions/{ai_action_id}/ Update an existing AI Action. Partial updates are not currently supported. Use the [Get AI Action](/ai-actions/how-tos/stored/manage/get-action) endpoint to get the action details first. # Run a stored action post /api/v2/ai-actions/{ai_action_id}/execute/ Given an action ID and instructions, this will execute the action and return the results. # Introduction AI Actions exposes Zapier's 7,000+ apps and 30,000+ actions, for selected partners, to build your own custom AI assistants. You can use the API to: * Send messages in Slack * Add a row to a Google Sheet * Draft a new email in Gmail * And thousands of other app actions, all with one universal natural language API. AI Actions is optimized for receiving user input in natural language like chat, assistant, or other large language model based experience. Think of AI Actions as a more human-friendly integrations API. ## Integrations made easy AI Actions contains a decade of Zapier's experience in solving API shenanigans, so you don't have to. Here are some common API complexities, automatically handled by AI Actions. * **Support for every type of auth**: Zapier securely handles and signs requests for you including Basic, Session, API Key, OAuth v1, Oauth v2, and Digest. * **Support for create, update, and search actions**: With endpoints optimized for natural language usage. * **Support for custom fields**: Spreadsheet, CRM, and mailing list friendly. * **Reference by name, not ID**: Humans use natural language names, not IDs, to reference things in their apps, so AI Actions does too. * **Smart, human defaults**: APIs sometimes have 100 options. Zapier's platform data helps us make AI Actions simpler for users out of the box. ## API design notes Here are a few design choices we've made with this API. * Let individual users control access to their actions and accounts. * Minimize the amount of work users must do to set up and run actions. * Let users override the AI when desired. # Authentication # Introduction There are two methods that can be used to authenticate with `@zapier/ai-actions`: * [API Key](#api-key): If you plan on only using the AI Actions client to interact with AI Actions on your behalf * [OAuth](#oauth): If you plan on creating an OAuth app to allow users to interact with AI Actions on their behalf ## API Key Your API key can be retrieved from the [Credentials page](https://actions.zapier.com/credentials/). **Treat your API key like a password.** It can be used to run your AI Actions. For example: if you set up a "Gmail: Find email" action, anyone with your API key can read all your email. Create an `AiActions` client with the API key: ```ts import { AiActions } from "@zapier/ai-actions"; const client = new AiActions({ auth: { apiKey: "YOUR_API_KEY", }, }); ``` ## OAuth ### Creating an OAuth app Click here to create a new OAuth app to use for authenticating with AI Actions. In order to work with the API client, **your app must have "Public Client" checked.** ### Getting an OAuth token #### Creating the `AiActionsAuth` object `@zapier/ai-actions` provides a helper class to handle the auth process. This is done with the `AiActionsAuth` class: ```ts import { AiActionsAuth } from "@zapier/ai-actions"; const aiActionsAuth = new AiActionsAuth({ clientId: "YOU_APP_CLIENT_ID", redirectUri: "YOUR_APP_REDIRECT_URI", }); ``` #### Storing the code verifier securely `@zapier/ai-actions` uses the [OAuth 2.0 PKCE flow](https://www.oauth.com/playground/authorization-code-with-pkce.html) to facilitate the OAuth process. As part of this, a "code verifier" is generated. By default, `AiActionsAuth` will store the verifier in the browser's `localStorage`. **This is not recommended for production use** since it can be easily accessed by malicious scripts, and it will not work server-side. To facilitate storing the code verifier securely, the constructor for `AiActionsAuth` has options that can be used. ```ts import { AiActionsAuth } from "@zapier/ai-actions"; const aiActionsAuth = new AiActionsAuth({ clientId: "YOU_APP_CLIENT_ID", redirectUri: "YOUR_APP_REDIRECT_URI", async storeVerifier(verifier) { // store the verifier somewhere secure for your user (i.e. database or KV store) }, async getVerifier(): Promise { // this function MUST return the verifier stored for the user by `storeVerifier` // each verifier can only be used once, and it must be consistend throughout the OAuth flow }, }); ``` #### Generating the authorization OR quick account creation URL Once you have an `AiActionsAuth` object, you can use it to generate the authorization URL: ```tsx const authUrl = await aiActionsAuth.generateAuthUrl(); // ... Authenticate with AI Actions; ``` This URL can be used to redirect the user to the authorization page. Once the user has authorized your app, they will be redirected to the `redirectUri` you provided. *** You can also generate a **quick account creation** URL. This will ensure that the user has a Zapier account before authorizing your app. If they do not have a Zapier account, one will be created for them. If they already have a Zapier account, they will be asked to log in on zapier.com. ```tsx const quickAccountCreationUrl = await aiActionsAuth.generateCreateAccountUrl( "Firstname", "Lastname", "user@example.com" ); // ... Authenticate with AI Actions; ``` After going through this flow, they will end up back on the `redirectUri` that you provided. #### Getting an access token After authorizing your app, the user will be redirected to the `redirectUri` you provided along with a `code` query parameter. This `code` can now be used to get an access token ```ts import { AiActions } from "@zapier/ai-actions"; // `code` will be in the query params; get it however you like (most likely server-side) const urlParams = new URLSearchParams(window.location.search); const code = urlParams.get("code"); // this access token can now be used to generate an AiActions client const oauthToken = await aiActionsAuth.getToken(code); const aiActionsClient = new AiActions({ auth: { token: oauthToken.access_token, }, }); try { // this will pass if auth succeeds, or throw an error if it fails await aiActionsClient.checkAuth(); } catch (e) { console.error("Error checking AI Actions auth", e); } ``` #### Refreshing the access token Access tokens expire after a certain amount of time. To refresh the token, you can use the `refreshToken` method along with the `refresh_token`: ```ts import { OAuthAccessToken, refreshOAuthToken, tokenNeedsRefresh, } from "@zapier/ai-actions"; // get the stored token for the current user; `getAiActionsToken` is a placeholder for your own function const oauthToken: OAuthAccessToken = await getAiActionsToken(); if (tokenNeedsRefresh(oauthToken)) { const refreshed = await refreshOAuthToken({ clientId: "YOUR_CLIENT_ID", refreshToken: oauthToken.refresh_token, }); if (refreshed) { // `setAiActionsToken` is a placeholder for your own function await setAiActionsToken(refreshed); } } ``` # Getting started ### **The `@zapier/ai-actions` package is still in development!** If you want to check it out, please [contact us](https://nla.zapier.app/_z/embed/page/clh5sdteo0001ml0pdz8a2aqr?&) The `@zapier/ai-actions` library makes it easy to interact with AI Actions from the client or the server. The library includes an API client, Typescript types, and utilities to make authentication easy. ## Installation To install the library, run: ```bash # npm npm install @zapier/ai-actions # pnpm pnpm add @zapier/ai-actions # yarn yarn add @zapier/ai-actions ``` ## Quick start [Get your API Key here](https://actions.zapier.com/credentials/) Create a new `AiActions` client with your API key: ```ts import { AiActions } from "@zapier/ai-actions"; const aiActionsClient = new AiActions({ auth: { apiKey: "sk-YOUR_API_KEY", }, }); ``` Use the client: ```ts const actionList = await aiActionsClient.getActionList(); actionList.results.forEach((action) => { console.log(action.id, action.description); }); ``` ## Next steps Set up OAuth to allow users to interact with AI Actions on their behalf Check out some examples of how to use the library Set up the library with Next.js See how to use the React component library # Next.js This page details recommended ways to use the `@zapier/ai-actions` library with [Next.js](https://nextjs.org/). The examples here are using the [Next.js app router](https://nextjs.org/docs/app). For storage, these examples are using [Vercel KV](https://vercel.com/docs/storage/vercel-kv) but any other form of server-side storage can be used. It's assumed that your Next.js app also has authentication set up, using a library such as [NextAuth.js](https://next-auth.js.org/). # Set up environment variables After [generating your OAuth client](/ai-actions/libraries/nodejs/authentication#getting-an-oauth-token), you can set your client ID and redirect URL inside of your `.env` file: ```sh .env NEXT_PUBLIC_ZAPIER_AI_ACTIONS_OAUTH_CLIENT_ID=nla-YOUR_CLIENT_ID NEXT_PUBLIC_ZAPIER_AI_ACTIONS_OAUTH_REDIRECT_URI=https://example.com/ai-actions-auth-callback ``` The `NEXT_PUBLIC_` prefix ensures that they can be referenced client-side. # Handle authentication server-side Authentication with AI Actions can be handled fully server-side. ```ts @/lib/ai-actions/server.ts import "server-only"; // make sure this code only ever runs on the server // using `@vercel/kv` as an example, but you can use any server-side storage import { kv } from "@vercel/kv"; import { AiActionsAuth, OAuthAccessToken, refreshOAuthToken, tokenNeedsRefresh, } from "@zapier/ai-actions"; /** * @param email User's email * @returns OAuth token to use for AI Actions API calls */ export async function getAiActionsToken( email: string ): Promise { // NOTE: You don't have to use email here; it can be any sort of user identifier const token = await kv.hgetall<{ token: string }>( `ai-actions-token:${email}` ); if (!token?.token) { return null; } const oauthToken = token.token as unknown as OAuthAccessToken; if (tokenNeedsRefresh(oauthToken)) { console.log(`Refreshing AI Actions token for ${email}`); const refreshed = await refreshOAuthToken({ clientId: process.env.NEXT_PUBLIC_ZAPIER_AI_ACTIONS_OAUTH_CLIENT_ID!, refreshToken: oauthToken.refresh_token, }); if (refreshed) { // see below; this just stores the token in the KV store await setAiActionsToken(email, refreshed); return refreshed; } } // typescript thinks this is a string, but it's actually an object return token.token as unknown as OAuthAccessToken; } /** * @param email User's email * @param token AI Actions OAuth token to set for the user */ export async function setAiActionsToken( email: string, token: OAuthAccessToken | null ) { await kv.hset(`ai-actions-token:${email}`, { token: JSON.stringify(token) }); } /** * @param session Current user's session * @returns AI Actions auth object to use for OAuth */ export const getAiActionsAuth = (email: string) => new AiActionsAuth({ clientId: process.env.NEXT_PUBLIC_ZAPIER_AI_ACTIONS_OAUTH_CLIENT_ID!, redirectUri: process.env.NEXT_PUBLIC_ZAPIER_AI_ACTIONS_OAUTH_REDIRECT_URI!, async storeVerifier(verifier) { await kv.hset(`ai-actions-verifier:${email}`, { verifier }); }, async getVerifier(): Promise { const key = `ai-actions-verifier:${email}`; const verifier = await kv.hgetall<{ verifier: string }>(key); // this can only be used once, so we delete it after getting it await kv.hdel(key, "verifier"); return verifier?.verifier || ""; }, }); ``` # Generating the authorization URL Here is an example of a button that will initiate authentication with AI Actions, using the server-side code from above. ```tsx initiate-ai-actions-auth.tsx "use server"; import { getAiActionsAuth } from "@/lib/ai-actions/server"; import { auth } from "@/auth"; import { Session } from "@/lib/types"; import Link from "next/link"; export const InitiateAiActionsAuth = async () => { const session = (await auth()) as Session; const aiActionsAuth = getAiActionsAuth(session.user.email); const url = await aiActionsAuth.generateAuthUrl(); return (
Please authenticate with AI Actions to proceed
Authenticate with AI Actions
); }; ``` # Getting and storing the access token To get the access token after the user has authenticated, a page needs to exist at `NEXT_PUBLIC_ZAPIER_AI_ACTIONS_OAUTH_REDIRECT_URI` that will handle the OAuth flow. ```tsx @/app/NEXT_PUBLIC_ZAPIER_AI_ACTIONS_OAUTH_REDIRECT_URI/page.tsx import { auth } from "@/auth"; import { Session } from "@/lib/types"; import { getAiActionsAuth, setAiActionsToken } from "@/lib/ai-actions/server"; import { redirect } from "next/navigation"; /** * The user will get redirected here after they login to Zapier/AI Actions. * * This will store the OAuth access token for the user. */ export default async function LoginSuccess({ searchParams, }: { searchParams: { code: string }; }) { const { code } = searchParams; const session = (await auth()) as Session; const aiActionsAuth = getAiActionsAuth(session.user.email); const response = await aiActionsAuth.getToken(code); if (response) { await setAiActionsToken(session.user.email, response); } else { console.error("Error getting AI Actions token", response); return redirect("/error"); } return redirect("/"); } ``` # Using the access token to create an `AiActions` client Once the token is stored, it can be used to get an `AiActions` client that can be used to make API calls. It can also be passed to the `AiActionsProvider` if you're using the `@zapier/ai-actions-react` library. Make sure that the `refresh_token` for the OAuth token doesn't leave the server ```tsx @/app/example-route/page.tsx import { AiActions } from "@zapier/ai-actions"; import { Session } from "@/lib/types"; import { getAiActionsToken, setAiActionsToken } from "@/lib/ai-actions/server"; import { ExampleClientComponent } from "./example-component"; export default async function ExamplePage() { const session = (await auth()) as Session; let aiActionsToken = session?.user ? await getAiActionsToken(session.user.email) : null; if (aiActionsToken) { const aiActionsClient = new AiActions({ auth: { token: aiActionsToken.access_token, }, }); try { await aiActionsClient.checkAuth(); } catch (e) { console.error("Error checking AI Actions auth", e); aiActionsToken = null; setAiActionsToken(session.user.email, null); } } return ; } ``` ```tsx @/app/example-route/example-component.tsx "use client"; import { AiActionsProvider, ActionList } from "@zapier/ai-actions-react"; export const ExampleComponent = ({ aiActionsToken, }: { aiActionsToken: string; }) => { return ( ); }; ``` # Usage examples # Introduction The AI Actions API client can be used to interact with any of the API endpoints that AI Actions supports. Below are a few examples of common uses for the client. # Creating a client See the [authentication guide](/ai-actions/libraries/nodejs/authentication) for more information on how to authenticate. ```ts import { AiActions } from "@zapier/ai-actions"; const aiActionsClient = new AiActions({ auth: { apiKey: "YOUR-API-KEY", // or... token: "OAUTH-TOKEN", }, }); ``` # Checking a user's authentication This is useful if you want to check if a user's AI Actions OAuth token is valid. ```ts try { await aiActionsClient.checkAuth(); } catch (error) { console.error("User is not authenticated", error); } ``` # Error handling The `@zapier/ai-actions` package exports an `AiActionsHttpError` type that can be used to get JSON from errors. ```ts import { AiActionsHttpError } from "@zapier/ai-actions"; try { await aiActionsClient .executeAction // ... (); } catch (error) { if (error instanceof AiActionsHttpError) { const parsedError = await error.response.json(); console.error("Error executing action", parsedError); } } ``` # Listing a user's actions Actions can be created or edited either on the [AI Actions website](https://actions.zapier.com/providers/) or using the [`@zapier/ai-actions-react` library](/ai-actions/libraries/react/getting-started) ```ts const actionList = await aiActionsClient.getActionList(); actionList?.results.forEach((action) => { // Each action has an ID that can be used to execute it, and it includes information about how the user // has set it up, such as the description and the app it's associated with. console.log(action.id, action.description); // "01EXAMPLE_ID Gmail: Find Email" }); ``` # Executig an action See the [Run a stored action guide](/ai-actions/how-tos/stored/run-stored-action) for more information on the available parameters. ```ts const result = await aiActionsClient.executeAction( { ai_action_id: "YOUR_ACTION_ID", }, { instructions: "Create a row with the following data....", params: { spreadsheet: { mode: "guess", // AI Actions will figure out the proper ID to use based on the hint, // that way you don't need to worry about knowing IDs! value: "My Spreadsheet", }, }, preview_only: false, } ); console.log(result?.resolved_params, result?.full_results); ``` # Search for Zapier apps and actions ```ts const appSearch = await aiActionsClient.searchApps({ query: "Google Sheets" }); appSearch?.results.forEach(async ({ name, app }) => { console.log(name); const actionSearch = await aiActionsClient.searchActions({ app, // omit `query` to get all actions for the app query: "add spreadsheet row", }); }); ``` # Give feedback on an action run If an execution doesn't work properly, you can provide feedback on it to help us improve the AI. ```ts const result = await aiActionsClient.executeAction({ // ... }); if (result) { await aiActionsClient.rateExecution({ execution_log_id: result.execution_log_id, // -1: Negative feedback // 0: Neutral feedback // 1: Positive feedback rating: -1, feedback: "It didn't work for me!", }); } ``` # ActionList The `ActionList` component can be used to list all of the current [stored actions](/ai-actions/how-tos/stored/intro) that are available for a user. If you are using an API key for authentication, then the stored actions listed will be only for that API Key. If you are using OAuth for authentication, then the stored actions listed will only be the actions that a user has set up for your OAuth provider. ## Props ### `onActionSelected` This is called when the user clicks on an action in the list. It is passed the `AiAction` object that was clicked. See the [List stored actions](/ai-actions/how-tos/stored/list-actions) documentation for more information about what this object contains. ## Usage Make sure that this component is rendered unerneath an [`AiActionsProvider`](/ai-actions/libraries/react/ai-actions-provider)! See [EditAction and CreateAction](/ai-actions/libraries/react/edit-action) for a more complete example of usage. ```tsx ai-action-list.tsx import { AiAction } from "@zapier/ai-actions"; import { ActionList } from "@zapier/ai-actions-react"; export const AiActionList = () => { return console.log(action)} />; }; ``` ## Example On the left is the `` component. Click on an action to see the details on the right. ``` Where `https://api.zapier.com/v1/embed/trello/create/113` is the `create_url` value of the Zap template. Optionally, you can add additional parameters to the `create_url` to [prefill the user's Zap](/partner-solutions/pre-filled-zaps) with custom values, simplifying the Zap configuration for the user. ## Option 2: Create Zaps without Zap Templates You can also facilitate a user's Zap creation via URL parameters instead of an existing Zap Template. This provides flexibility to redirect users to a pre-populated Zap Editor with known context from your app without publishing a Zap Template for each specific use case. [Use the Zap Pre-fill Generator](/partner-solutions/pre-filled-zaps#creating-pre-filled-zaps-using-the-zap-generator)  to easily construct pre-filled Zaps for your embedded editor experience or as a lightweight entry point into the Zap Editor from your app. ## Editing existing Zaps Use the Workflow API to load a user's Zaps (using the [`GET /v1/zaps` endpoint](/partner-solutions/api-reference/zaps/get-zaps-\[v1])). When the user chooses to open or edit a Zap use the the `url` value of the Zap as the source of an embedded frame like this: ```js ``` Where `https://zapier.com/editor/123456` is the `url` of the Zap to be edited. If you prefer, you can open these URLs in a separate window, new tab, or popup from your app. ## `postMessage` events If you decide to embed the Zap editor within your product you can listen to [message events from `postMessage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/message_event) to help you improve the interactivity with the iframe (e.g. automatically close the iframe modal.) The messages available include: * `zap:unpause` = Zap turned on / published * `zap:unpause:done` = Zap turned on / published (success) * `zap:unpause:fail` = Zap turned on / published (failure) * `zap:pause` = Zap turned off * `zap:pause:done` = Zap turned off (success) * `zap:pause:fail` = Zap turned off (failure) ## Turning off a Zap The API does not currently have an endpoint to turn off/on a user's Zaps. If your Zapier app uses [Webhook Subscriptions](https://platform.zapier.com/build/hook-trigger), you can send a `DELETE` to the unique target URL that was provided when the subscription was created and that will then pause/turn off a Zap. # Integrate the Workflow API Our most powerful tool for building native workflows in your product The Workflow API is a powerful tool for building native feeling integrations and workflows for your end users. It allows your app access to the industry's largest integration directory that spans over 7,000 apps, enabling you to easily build and manage the most impactful workflows for your users. This tool enables users to discover, craft, and manage workflows from directly within your product while being customized to your product's look and feel, offering a seamless integration experience. Whether you want to build an end-to-end native feeling integration for your users, or surface the most popular zap templates customized to your product's branding, the Workflow API extends your product's functionality by showcasing premier Zapier-powered workflows exactly where your users need them the most—in the very heart of your tool. It allows for customization in styling, simplifies the Zap setup process for users, and provides immediate access to pertinent Zap details, ensuring a cohesive and intuitive user experience. The Workflow API is accessible for all publicly listed integrations. ## Capabilities Get a list of all the apps available in Zapier's app directory to power your own integration marketplace and show your users all the integration possibilities with your Zapier integration. Have complete style control over how you present Zap templates in your product. The Workflow API gives you access to the raw Zap Template data so you can give your users access to your Zap templates with your product's style, look and feel. Define input fields on behalf of your users, simplying the experience of setting up their Zap Embed our Zap Editor to allow your users to create new Zaps and modify existing ones, without needing to leave your product. Build native feeling integrations to your app powered by the Workflow APIs to enable your users to create automated workflows from within your product. Show users the Zaps they have set up from right within your product, keeping them on your site longer and giving them complete confidence in your Zapier integration. *** Check out the recent ZapConnect Session on the Workflow API, discussing features & popular use cases.