Dive into the nitty gritty details about how to use the API.
Here's a basic example of how you can use the API:
curl -v \
-d '{"instructions": "Add Bryan Helmig at Zapier to my test sheet, oh and he loves guitars!"}' \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
'https://actions.zapier.com/api/v1/dynamic/exposed/<ACTION_ID>/execute/'
Mix in some fixed values:
curl -v \
-d '{"instructions": "Send a short poem about automation to slack", "channel": "#fun-zapier"}' \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
'https://actions.zapier.com/api/v1/dynamic/exposed/<ACTION_ID>/execute/'
AI Actions is optimized for a chat-style usage paradigm where you want to offload as much work to a large language model (LLM), as possible. An action is run ("executed") via an API call with one single natural language parameter: instructions
.
In the chat use case, these instructions are likely being generated by your own LLM. However, AI Actions works just as well even in more traditional software paradigm where instructions are perhaps hard-coded into your codebase or supplied by the user directly.
Whatever your use case is, AI Actions utilizes AI to attempt to "guess" field values required to run actions. This saves users tons of time in setting up their actions.
Consider the case where you've built a chat product and your end user wants to expose a "Send Slack Message" action to your product. Their action setup might look like this.
The user only has to select their desired action ("Slack: Send Channel Message") and authorize their Slack account.
By default, all required fields are set to "Have AI guess a value for this field". We call these fields "hint parameters".
In this example there are two required fields: Channel
and Message Text
.
If a field uses "Have AI guess a value for this field", two things happen:
instructions
to fill in the values for Channel
and Message Text
. AI Actions is smart about fields like Channel
where Slack's API requires a channel ID rather than a plain text channel name. AI Actions handles all such cases automatically.instructions
guessing.Sometimes language models hallucinate or guess wrong. And if this were a particuarly sensitive Slack message, the user may not want to leave the selection of Channel
up to chance. AI Actions allows the user to use a specific, fixed value like this.
Now when the action is executed, Message Text
will be automatically guessed, but Channel
will be set to "#testing". This ability to override field hints significantly increases user trust and unlocks use cases where the user may have partial, but not full trust, in an AI guessing.
Hint parameters are always optional. When running actions via the API, you, the provider, can choose to supply none/any/all hint parameters. Any hint parameters provided are treated exactly like an action field set to "Use a specific value" as an override.
Zapier supports custom fields throughout the platform. The degenerate case is a spreadsheet, where every column is a custom field. This introduces complexity because spreadsheet columns are unknowable at action setup time if the user sets the action field that selects which spreadsheet to use as "Have AI guess a value for this field" (i.e. the spreadsheet will be chosen dynmically when the action is run).
AI Actions handles such custom fields using the same pattern as above with one distinction: they are not listed as hint parameters because they are literally unknowable until run time. Also, as you may expect, if the user picks a specific spreadsheet during action setup, custom fields act like regular fields and flow through normally.
In the typical chat product use case, you'll want to expose these hint parameters alongside the exposed action list to your own language model. Your LLM is likely to have broader context about the user vs the narrowly constrained instructions
string passed to the API, and will therefore produce a better guess.
In summary:
[user supplied "Use specific value"] — overrides --> [API call supplied hint parameters] — overrides --> [API call supplied "instructions"]
There are three common API tasks:
Let's go through each, assuming you have a valid access token already.
# via the RESTful list endpoint:
curl -v -H "Authorization: Bearer <ACCESS_TOKEN>" https://actions.zapier.com/api/v1/dynamic/exposed/
# via the dynamic openapi.json schema:
curl -v -H "Authorization: Bearer <ACCESS_TOKEN>" https://actions.zapier.com/api/v1/dynamic/openapi.json
Excerpt of a list endpoint response (see full response):
{
"results": [
{
"id": "01GTB1KMX72QTJEXXXXXXXXXX",
"description": "Slack: Send Channel Message",
...
Excerpt of an openapi.json response (see full response):
{
...
"paths": {
...
"/api/v1/dynamic/exposed/01GTB1KMX72QTJEXXXXXXXXXX/execute/": {
"post": {
"operationId": "exposed_01GTB1KMX72QTJEXXXXXXXXXX_execute",
"summary": "Slack: Send Channel Message (execute)",
...
As a reminder, hint parameters are always optional. By default, all parameters are filled in via guessing based on a provided instructions
parameter. If a hint parameter is supplied in an API request along with instructions, the hint parameter will override the guess.
# via the RESTful list endpoint:
curl -v -H "Authorization: Bearer <ACCESS_TOKEN>" https://actions.zapier.com/api/v1/dynamic/exposed/
# via the dynamic openapi.json schema:
curl -v -H "Authorization: Bearer <ACCESS_TOKEN>" https://actions.zapier.com/api/v1/dynamic/openapi.json
Excerpt of a list endpoint response (see full response):
{
"results": [
{
"id": "01GTB1KMX72QTJEXXXXXXXXXX",
"description": "Slack: Send Channel Message",
"input_params": {
"instructions": "str",
"Message_Text": "str",
"Channel": "str",
...
Excerpt of an openapi.json response (see full response):
{
...
"components": {
"schemas": {
...
"PreviewExecuteRequest_01GTB1KMX72QTJEXXXXXXXXXX": {
"title": "PreviewExecuteRequest_01GTB1KMX72QTJEXXXXXXXXXX",
"type": "object",
"properties": {
"instructions": {
...
},
"Message_Text": {
...
},
"Channel_Name": {
...
}
Note: Every list of input params will contain instructions
- the only required parameter for action execution.
Finally, with an action ID and any optional hint parameters in hand, we can run ("execute") an action.
curl -v \
-d '{"instructions": "send a short poem about automation and robots to slack", "Channel_Name": "#fun-zapier"}' \
-H "Content-Type: application/json" \
-X POST 'https://actions.zapier.com/api/v1/dynamic/exposed/01GTB1KMX72QTJEXXXXXXXXXX/execute/'
Another example, this time an action to retrieve data:
curl -v \
-d '{"instructions": "grab the latest email from bryan helmig"}' \
-H "Content-Type: application/json" \
-X POST 'https://actions.zapier.com/api/v1/dynamic/exposed/01GTA3G1WD49GN1XXXXXXXXX/execute/'
One more example, this time requesting a preview of the action:
curl -v \
-d '{"instructions": "say Hello World to #fun-zapier", "preview_only": true}' \
-H "Content-Type: application/json" \
-X POST 'https://actions.zapier.com/api/v1/dynamic/exposed/01GTB1KMX72QTJEXXXXXXXXXX/execute/'
The API response to executing an action will contain a status
key, which can be one of four values.
1. "success"
The action executed successfully and found results.
2. "error"
The action failed to execute. An error
key will have its value populated.
For example:
{
...
"action_used": "Gmail: Send Email",
"result": null,
"status": "error",
"error": "Error from app: Required field \"subject\" (subject) is missing. Required field \"Body\" (body) is missing."
}
3. "empty"
The action executed successfully, but no results were found. This status exists to be explicit that having an empty result
is correct.
4. "preview"
The action is a preview and not a real execution. A review_url
key will contain a URL to optionally execute the action from a browser, or you can call the endpoint again without the preview_only
input parameter.
For example:
{
...
"action_used": "Slack: Send Channel Message",
"input_params": {
"Channel": "fun-zapier",
"Message_Text": "Hello World"
},
"review_url": "https://actions.zapier.com/execution/01GW2E2ZNE5W07D32E41HFT5GJ/?needs_confirmation=true",
"status": "preview",
}
All actions will return trimmed result
data. result
is ideal for humans and language models alike!
By default, full_results
is not included, but it can be useful for machines. Contact us if you'd like access to full results.
The trimmed version is created using some AI and heuristics:
Trimmed results are ideal for inserting directly back into the prompt context of an LLM without blowing up context token window limits.
Example of a trimmed results payload from "Gmail: Find Email":
{
"result": {
"from__email": "mike@zapier.com",
"from__name": "Mike Knoop",
"subject": "Re: Getting setup",
"body_plain": "Hi Karla, thanks for following up. I can confirm I got access to everything! ... Thanks! Mike",
"cc__emails": "bryan@zapier.com, wade@zapier.com"
"to__email": "Mike Knoop",
}
}
You made it through the most dense page in the AI Actions docs. 🏆