master-zapier-plan-draft/research/zapier/raw/coding-set.jsonl
George Lambert b4150c8250 Milestone 0: import zappier billing, Verae middleware, and Zapier research
Compose-ready workspace: packages/zappier (rate card, portal, Stripe),
packages/verae-zapier-middleware (timestamp + NATS), packages/verae-zapier
(CLI app), vendor/zapier-platform, and research/zapier vendor corpus.

Gate 0 structure checks pass. Product code and research are not yet wired.
2026-09-09 02:37:36 -04:00

208 lines
1.2 MiB
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{"_id": "schema_json:exported-schema", "kind": "schema_json", "key": "exported-schema", "title": "zapier-platform-schema 19.1.0 (exported JSON)", "summary": "Machine-checkable JSON Schema bundle for App definitions.", "body": "{\n \"version\": \"19.1.0\",\n \"schemas\": {\n \"AppSchema\": {\n \"id\": \"/AppSchema\",\n \"description\": \"Represents a full app.\",\n \"type\": \"object\",\n \"required\": [\n \"version\",\n \"platformVersion\"\n ],\n \"properties\": {\n \"version\": {\n \"description\": \"A version identifier for your code.\",\n \"$ref\": \"/VersionSchema\"\n },\n \"platformVersion\": {\n \"description\": \"A version identifier for the Zapier execution environment.\",\n \"$ref\": \"/VersionSchema\"\n },\n \"beforeApp\": {\n \"description\": \"EXPERIMENTAL: Before the perform method is called on your app, you can modify the execution context.\",\n \"$ref\": \"/MiddlewaresSchema\"\n },\n \"afterApp\": {\n \"description\": \"EXPERIMENTAL: After the perform method is called on your app, you can modify the response.\",\n \"$ref\": \"/MiddlewaresSchema\"\n },\n \"authentication\": {\n \"description\": \"Choose what scheme your API uses for authentication.\",\n \"$ref\": \"/AuthenticationSchema\"\n },\n \"requestTemplate\": {\n \"description\": \"Define a request mixin, great for setting custom headers, content-types, etc.\",\n \"$ref\": \"/RequestSchema\"\n },\n \"beforeRequest\": {\n \"description\": \"Before an HTTP request is sent via our `z.request()` client, you can modify it.\",\n \"$ref\": \"/MiddlewaresSchema\"\n },\n \"afterResponse\": {\n \"description\": \"After an HTTP response is recieved via our `z.request()` client, you can modify it.\",\n \"$ref\": \"/MiddlewaresSchema\"\n },\n \"hydrators\": {\n \"description\": \"An optional bank of named functions that you can use in `z.hydrate('someName')` to lazily load data.\",\n \"$ref\": \"/HydratorsSchema\"\n },\n \"resources\": {\n \"description\": \"All the resources for your app. Zapier will take these and generate the relevent triggers/searches/creates automatically.\",\n \"$ref\": \"/ResourcesSchema\"\n },\n \"triggers\": {\n \"description\": \"All the triggers for your app. You can add your own here, or Zapier will automatically register any from the list/hook methods on your resources.\",\n \"$ref\": \"/TriggersSchema\"\n },\n \"bulkReads\": {\n \"description\": \"All of the read bulks (GETs) your app exposes to retrieve resources in batches.\",\n \"$ref\": \"/BulkReadsSchema\"\n },\n \"searches\": {\n \"description\": \"All the searches for your app. You can add your own here, or Zapier will automatically register any from the search method on your resources.\",\n \"$ref\": \"/SearchesSchema\"\n },\n \"creates\": {\n \"description\": \"All the creates for your app. You can add your own here, or Zapier will automatically register any from the create method on your resources.\",\n \"$ref\": \"/CreatesSchema\"\n },\n \"searchOrCreates\": {\n \"description\": \"All the search-or-create combos for your app. You can create your own here, or Zapier will automatically register any from resources that define a search, a create, and a get (or define a searchOrCreate directly). Register non-resource search-or-creates here as well.\",\n \"$ref\": \"/SearchOrCreatesSchema\"\n },\n \"searchAndCreates\": {\n \"description\": \"An alias for \\\"searchOrCreates\\\".\",\n \"$ref\": \"/SearchAndCreatesSchema\"\n },\n \"flags\": {\n \"description\": \"Top-level app options\",\n \"$ref\": \"/AppFlagsSchema\"\n },\n \"throttle\": {\n \"description\": \"Zapier uses this configuration to apply throttling when the limit for the window is exceeded. When set here, it is the default throttle configuration used on each action of the integration. And when set in an action's operation object, it gets overwritten for that action only.\",\n \"$ref\": \"/ThrottleObjectSchema\"\n },\n \"legacy\": {\n \"description\": \"**INTERNAL USE ONLY**. Zapier uses this to hold properties from a legacy Web Builder app.\",\n \"type\": \"object\",\n \"docAnnotation\": {\n \"hide\": true\n }\n },\n \"firehoseWebhooks\": {\n \"description\": \"**INTERNAL USE ONLY**. Zapier uses this for internal webhook app configurations.\",\n \"type\": \"object\",\n \"docAnnotation\": {\n \"hide\": true\n }\n }\n },\n \"additionalProperties\": false\n },\n \"FunctionRequireSchema\": {\n \"id\": \"/FunctionRequireSchema\",\n \"description\": \"A path to a file that might have content like `module.exports = (z, bundle) => [{id: 123}];`.\",\n \"type\": \"object\",\n \"required\": [\n \"require\"\n ],\n \"properties\": {\n \"require\": {\n \"type\": \"string\"\n }\n },\n \"additionalProperties\": false\n },\n \"FunctionSourceSchema\": {\n \"id\": \"/FunctionSourceSchema\",\n \"description\": \"Source code like `{source: \\\"return 1 + 2\\\"}` which the system will wrap in a function for you.\",\n \"type\": \"object\",\n \"required\": [\n \"source\"\n ],\n \"properties\": {\n \"source\": {\n \"type\": \"string\",\n \"pattern\": \"return\",\n \"description\": \"JavaScript code for the function body. This must end with a `return` statement.\"\n },\n \"args\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n },\n \"description\": \"Function signature. Defaults to `['z', 'bundle']` if not specified.\"\n }\n },\n \"additionalProperties\": false\n },\n \"FlatObjectSchema\": {\n \"id\": \"/FlatObjectSchema\",\n \"description\": \"An object whose values can only be primitives\",\n \"type\": \"object\",\n \"patternProperties\": {\n \"[^\\\\s]+\": {\n \"description\": \"Any key may exist in this flat object as long as its values are simple.\",\n \"anyOf\": [\n {\n \"type\": \"null\"\n },\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"integer\"\n },\n {\n \"type\": \"number\"\n },\n {\n \"type\": \"boolean\"\n }\n ]\n }\n },\n \"additionalProperties\": false\n },\n \"FunctionSchema\": {\n \"id\": \"/FunctionSchema\",\n \"description\": \"Internal pointer to a function from the original source or the source code itself. Encodes arity and if `arguments` is used in the body. Note - just write normal functions and the system will encode the pointers for you. Or, provide {source: \\\"return 1 + 2\\\"} and the system will wrap in a function for you.\",\n \"oneOf\": [\n {\n \"type\": \"string\",\n \"pattern\": \"^\\\\$func\\\\$\\\\d+\\\\$[tf]\\\\$$\"\n },\n {\n \"$ref\": \"/FunctionRequireSchema\"\n },\n {\n \"$ref\": \"/FunctionSourceSchema\"\n }\n ]\n },\n \"FieldChoiceWithLabelSchema\": {\n \"id\": \"/FieldChoiceWithLabelSchema\",\n \"description\": \"An object describing a labeled choice in a static dropdown. Useful if the value a user picks isn't exactly what the zap uses. For instance, when they click on a nickname, but the zap uses the user's full name ([image](https://cdn.zapier.com/storage/photos/8ed01ac5df3a511ce93ed2dc43c7fbbc.png)).\",\n \"type\": \"object\",\n \"required\": [\n \"value\",\n \"sample\",\n \"label\"\n ],\n \"properties\": {\n \"value\": {\n \"description\": \"The actual value that is sent into the Zap. This is displayed as light grey text in the editor. Should match sample exactly.\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"sample\": {\n \"description\": \"A legacy field that is no longer used by the editor, but it is still required for now and should match the value.\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"label\": {\n \"description\": \"A human readable label for this value.\",\n \"type\": \"string\",\n \"minLength\": 1\n }\n }\n },\n \"FieldChoicesSchema\": {\n \"id\": \"/FieldChoicesSchema\",\n \"description\": \"A static dropdown of options. Which you use depends on your order and label requirements:\\n\\nNeed a Label? | Does Order Matter? | Type to Use\\n---|---|---\\nYes | No | Object of value -> label\\nNo | Yes | Array of Strings\\nYes | Yes | Array of [FieldChoiceWithLabel](#fieldchoicewithlabelschema)\",\n \"oneOf\": [\n {\n \"type\": \"object\",\n \"minProperties\": 1,\n \"not\": {\n \"required\": [\n \"perform\"\n ]\n }\n },\n {\n \"type\": \"array\",\n \"minItems\": 1,\n \"items\": {\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"$ref\": \"/FieldChoiceWithLabelSchema\"\n }\n ]\n }\n }\n ]\n },\n \"PlainFieldSchema\": {\n \"id\": \"/PlainFieldSchema\",\n \"description\": \"In addition to the requirements below, the following keys are mutually exclusive:\\n\\n* `children` & `list`\\n* `children` & `dict`\\n* `children` & `type`\\n* `children` & `placeholder`\\n* `children` & `helpText`\\n* `children` & `default`\\n* `dict` & `list`\\n* `dynamic` & `dict`\\n* `dynamic` & `choices`\",\n \"type\": \"object\",\n \"required\": [\n \"key\"\n ],\n \"docAnnotation\": {\n \"hide\": true\n },\n \"properties\": {\n \"key\": {\n \"description\": \"A unique machine readable key for this value (IE: \\\"fname\\\").\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"label\": {\n \"description\": \"A human readable label for this value (IE: \\\"First Name\\\").\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"type\": {\n \"description\": \"The type of this value. Use `string` for basic text input, `text` for a large, `<textarea>` style box, and `code` for a `<textarea>` with a fixed-width font. Field type of `file` will accept either a file object or a string. If a URL is provided in the string, Zapier will automatically make a GET for that file. Otherwise, a .txt file will be generated.\",\n \"type\": \"string\",\n \"enum\": [\n \"string\",\n \"text\",\n \"integer\",\n \"number\",\n \"boolean\",\n \"datetime\",\n \"file\",\n \"password\",\n \"copy\",\n \"code\",\n \"json\"\n ]\n },\n \"required\": {\n \"description\": \"If this value is required or not.\",\n \"type\": \"boolean\"\n },\n \"default\": {\n \"description\": \"A default value that is saved the first time a Zap is created.\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"list\": {\n \"description\": \"Acts differently when used in inputFields vs. when used in outputFields. In inputFields: Can a user provide multiples of this field? In outputFields: Does this field return an array of items of type `type`?\",\n \"type\": \"boolean\"\n },\n \"children\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"/PlainFieldSchema\"\n },\n \"description\": \"An array of child fields that define the structure of a sub-object for this field. Usually used for line items.\",\n \"minItems\": 1\n },\n \"dict\": {\n \"description\": \"Is this field a key/value input?\",\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n },\n \"AuthFieldSchema\": {\n \"id\": \"/AuthFieldSchema\",\n \"description\": \"Field schema specialized for authentication fields. In addition to the requirements below, the following keys are mutually exclusive:\\n\\n* `children` & `list`\\n* `children` & `dict`\\n* `children` & `type`\\n* `children` & `placeholder`\\n* `children` & `helpText`\\n* `children` & `default`\\n* `dict` & `list`\\n* `dynamic` & `dict`\\n* `dynamic` & `choices`\",\n \"required\": [\n \"key\"\n ],\n \"type\": \"object\",\n \"properties\": {\n \"key\": {\n \"description\": \"A unique machine readable key for this value (IE: \\\"fname\\\").\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"label\": {\n \"description\": \"A human readable label for this value (IE: \\\"First Name\\\").\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"type\": {\n \"description\": \"The type of this value used to be.\",\n \"type\": \"string\",\n \"enum\": [\n \"string\",\n \"number\",\n \"boolean\",\n \"datetime\",\n \"copy\",\n \"password\",\n \"integer\",\n \"text\"\n ]\n },\n \"required\": {\n \"description\": \"If this value is required or not. This defaults to `true`.\",\n \"type\": \"boolean\"\n },\n \"default\": {\n \"description\": \"A default value that is saved the first time a Zap is created.\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"list\": {\n \"description\": \"Acts differently when used in inputFields vs. when used in outputFields. In inputFields: Can a user provide multiples of this field? In outputFields: Does this field return an array of items of type `type`?\",\n \"type\": \"boolean\"\n },\n \"children\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"/AuthFieldSchema\"\n },\n \"description\": \"An array of child fields that define the structure of a sub-object for this field. Usually used for line items.\",\n \"minItems\": 1\n },\n \"dict\": {\n \"description\": \"Is this field a key/value input?\",\n \"type\": \"boolean\"\n },\n \"helpText\": {\n \"description\": \"A human readable description of this value (IE: \\\"The first part of a full name.\\\"). You can use Markdown.\",\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 1000\n },\n \"placeholder\": {\n \"description\": \"An example value that is not saved.\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"choices\": {\n \"description\": \"An object of machine keys and human values to populate a static dropdown.\",\n \"$ref\": \"/FieldChoicesSchema\"\n },\n \"computed\": {\n \"description\": \"Is this field automatically populated (and hidden from the user)? Note: Only OAuth and Session Auth support fields with this key.\",\n \"type\": \"boolean\"\n },\n \"inputFormat\": {\n \"description\": \"Useful when you expect the input to be part of a longer string. Put \\\"{{input}}\\\" in place of the user's input (IE: \\\"https://{{input}}.yourdomain.com\\\").\",\n \"type\": \"string\",\n \"pattern\": \"^.*{{input}}.*$\"\n },\n \"isNoSecret\": {\n \"description\": \"Indicates if this authentication field is safe to e.g. be stored without encryption or displayed (not a secret).\",\n \"type\": \"boolean\"\n }\n }\n },\n \"RequestSchema\": {\n \"id\": \"/RequestSchema\",\n \"description\": \"A representation of a HTTP request - you can use the `{{syntax}}` to inject authentication, field or global variables.\",\n \"type\": \"object\",\n \"properties\": {\n \"method\": {\n \"description\": \"The HTTP method for the request.\",\n \"type\": \"string\",\n \"default\": \"GET\",\n \"enum\": [\n \"GET\",\n \"PUT\",\n \"POST\",\n \"PATCH\",\n \"DELETE\",\n \"HEAD\"\n ]\n },\n \"url\": {\n \"description\": \"A URL for the request (we will parse the querystring and merge with params). Keys and values will not be re-encoded.\",\n \"type\": \"string\"\n },\n \"body\": {\n \"description\": \"Can be nothing, a raw string or JSON (object or array).\",\n \"oneOf\": [\n {\n \"type\": \"null\"\n },\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"object\"\n },\n {\n \"type\": \"array\"\n }\n ]\n },\n \"params\": {\n \"description\": \"A mapping of the querystring - will get merged with any query params in the URL. Keys and values will be encoded.\",\n \"$ref\": \"/FlatObjectSchema\"\n },\n \"headers\": {\n \"description\": \"The HTTP headers for the request.\",\n \"$ref\": \"/FlatObjectSchema\"\n },\n \"auth\": {\n \"description\": \"An object holding the auth parameters for OAuth1 request signing, like `{oauth_token: 'abcd', oauth_token_secret: '1234'}`. Or an array reserved (i.e. not implemented yet) to hold the username and password for Basic Auth. Like `['AzureDiamond', 'hunter2']`.\",\n \"oneOf\": [\n {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\",\n \"minProperties\": 2,\n \"maxProperties\": 2\n }\n },\n {\n \"$ref\": \"/FlatObjectSchema\"\n }\n ]\n },\n \"removeMissingValuesFrom\": {\n \"description\": \"Should missing values be sent? (empty strings, `null`, and `undefined` only \\u2014 `[]`, `{}`, and `false` will still be sent). Allowed fields are `params` and `body`. The default is `false`, ex: ```removeMissingValuesFrom: { params: false, body: false }```\",\n \"type\": \"object\",\n \"properties\": {\n \"params\": {\n \"description\": \"Refers to data sent via a requests query params (`req.params`)\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"body\": {\n \"description\": \"Refers to tokens sent via a requsts body (`req.body`)\",\n \"type\": \"boolean\",\n \"default\": false\n }\n },\n \"additionalProperties\": false\n },\n \"serializeValueForCurlies\": {\n \"description\": \"A function to customize how to serialize a value for curlies `{{var}}` in the request object. By default, when this is unspecified, the request client only replaces curlies where variables are strings, and would throw an error for non-strings. The function should accepts a single argument as the value to be serialized and return the string representation of the argument.\",\n \"$ref\": \"/FunctionSchema\"\n },\n \"skipThrowForStatus\": {\n \"description\": \"If `true`, don't throw an exception for response 400 <= status < 600 automatically before resolving with the response. Defaults to `false`.\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"skipEncodingChars\": {\n \"description\": \"Contains the characters that you want left unencoded in the query params (`req.params`). If unspecified, `z.request()` will percent-encode non-ascii characters and these reserved characters: ``:$/?#[]@$&+,;=^@`\\\\``.\",\n \"type\": \"string\"\n }\n },\n \"additionalProperties\": false\n },\n \"RedirectRequestSchema\": {\n \"id\": \"/RedirectRequestSchema\",\n \"description\": \"A representation of a HTTP redirect - you can use the `{{syntax}}` to inject authentication, field or global variables.\",\n \"type\": \"object\",\n \"properties\": {\n \"method\": {\n \"description\": \"The HTTP method for the request.\",\n \"type\": \"string\",\n \"default\": \"GET\",\n \"enum\": [\n \"GET\"\n ]\n },\n \"url\": {\n \"description\": \"A URL for the request (we will parse the querystring and merge with params). Keys and values will not be re-encoded.\",\n \"type\": \"string\"\n },\n \"params\": {\n \"description\": \"A mapping of the querystring - will get merged with any query params in the URL. Keys and values will be encoded.\",\n \"$ref\": \"/FlatObjectSchema\"\n }\n },\n \"additionalProperties\": false\n },\n \"AuthFieldsSchema\": {\n \"id\": \"/AuthFieldsSchema\",\n \"description\": \"An array or collection of authentication fields.\",\n \"type\": \"array\",\n \"items\": {\n \"oneOf\": [\n {\n \"$ref\": \"/AuthFieldSchema\"\n }\n ]\n }\n },\n \"AuthenticationBasicConfigSchema\": {\n \"id\": \"/AuthenticationBasicConfigSchema\",\n \"description\": \"Config for Basic Authentication. No extra properties are required to setup Basic Auth, so you can leave this empty if your app uses Basic Auth.\",\n \"type\": \"object\",\n \"properties\": {},\n \"additionalProperties\": false\n },\n \"AuthenticationCustomConfigSchema\": {\n \"id\": \"/AuthenticationCustomConfigSchema\",\n \"description\": \"Config for custom authentication (like API keys). No extra properties are required to setup this auth type, so you can leave this empty if your app uses a custom auth method.\",\n \"type\": \"object\",\n \"properties\": {\n \"sendCode\": {\n \"description\": \"EXPERIMENTAL: Define the call Zapier should make to send the OTP code.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n }\n },\n \"additionalProperties\": false\n },\n \"AuthenticationDigestConfigSchema\": {\n \"id\": \"/AuthenticationDigestConfigSchema\",\n \"description\": \"Config for Digest Authentication. No extra properties are required to setup Digest Auth, so you can leave this empty if your app uses Digets Auth.\",\n \"type\": \"object\",\n \"properties\": {},\n \"additionalProperties\": false\n },\n \"AuthenticationOAuth1ConfigSchema\": {\n \"id\": \"/AuthenticationOAuth1ConfigSchema\",\n \"description\": \"Config for OAuth1 authentication.\",\n \"type\": \"object\",\n \"required\": [\n \"getRequestToken\",\n \"authorizeUrl\",\n \"getAccessToken\"\n ],\n \"properties\": {\n \"getRequestToken\": {\n \"description\": \"Define where Zapier will acquire a request token which is used for the rest of the three legged authentication process.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"authorizeUrl\": {\n \"description\": \"Define where Zapier will redirect the user to authorize our app. Typically, you should append an `oauth_token` querystring parameter to the request.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RedirectRequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"getAccessToken\": {\n \"description\": \"Define how Zapier fetches an access token from the API\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n }\n },\n \"additionalProperties\": false\n },\n \"AuthenticationOAuth2ConfigSchema\": {\n \"id\": \"/AuthenticationOAuth2ConfigSchema\",\n \"description\": \"Config for OAuth2 authentication.\",\n \"type\": \"object\",\n \"required\": [\n \"authorizeUrl\",\n \"getAccessToken\"\n ],\n \"properties\": {\n \"authorizeUrl\": {\n \"description\": \"Define where Zapier will redirect the user to authorize our app. Note: we append the redirect URL and state parameters to return value of this function.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RedirectRequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"getAccessToken\": {\n \"description\": \"Define how Zapier fetches an access token from the API\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"refreshAccessToken\": {\n \"description\": \"Define how Zapier will refresh the access token from the API\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"codeParam\": {\n \"description\": \"Define a non-standard code param Zapier should scrape instead.\",\n \"type\": \"string\"\n },\n \"scope\": {\n \"description\": \"What scope should Zapier request?\",\n \"type\": \"string\"\n },\n \"autoRefresh\": {\n \"description\": \"Should Zapier invoke `refreshAccessToken` when we receive an error for a 401 response?\",\n \"type\": \"boolean\"\n },\n \"enablePkce\": {\n \"description\": \"Should Zapier use PKCE for OAuth2?\",\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n },\n \"AuthenticationSessionConfigSchema\": {\n \"id\": \"/AuthenticationSessionConfigSchema\",\n \"description\": \"Config for session authentication.\",\n \"type\": \"object\",\n \"required\": [\n \"perform\"\n ],\n \"properties\": {\n \"perform\": {\n \"description\": \"Define how Zapier fetches the additional authData needed to make API calls.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n }\n },\n \"additionalProperties\": false\n },\n \"RefResourceSchema\": {\n \"id\": \"/RefResourceSchema\",\n \"description\": \"Reference a resource by key and the data it returns. In the format of: `{resource_key}.{foreign_key}(.{human_label_key})`.\",\n \"type\": \"string\",\n \"pattern\": \"^[a-zA-Z0-9_]+\\\\.[a-zA-Z0-9_\\\\s\\\\[\\\\]]+(\\\\.[a-zA-Z0-9_\\\\s\\\\[\\\\]]+(,[a-zA-Z0-9_\\\\s\\\\[\\\\]]+)*)?$\"\n },\n \"FieldDynamicChoicesSchema\": {\n \"id\": \"/FieldDynamicChoicesSchema\",\n \"description\": \"Describes dynamic dropdowns powered by a perform function or request.\",\n \"type\": \"object\",\n \"required\": [\n \"perform\"\n ],\n \"properties\": {\n \"perform\": {\n \"description\": \"A function or request that returns choices for this dynamic dropdown.\",\n \"oneOf\": [\n {\n \"$ref\": \"/FunctionSchema\"\n },\n {\n \"$ref\": \"/RequestSchema\"\n }\n ]\n }\n },\n \"additionalProperties\": false\n },\n \"FieldMetaSchema\": {\n \"id\": \"/FieldMetaSchema\",\n \"type\": \"object\",\n \"description\": \"Allows for additional metadata to be stored on the field.\",\n \"patternProperties\": {\n \"[^\\\\s]+\": {\n \"description\": \"Only string, integer or boolean values are allowed.\",\n \"anyOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"integer\"\n },\n {\n \"type\": \"boolean\"\n }\n ]\n }\n }\n },\n \"KeySchema\": {\n \"id\": \"/KeySchema\",\n \"description\": \"A unique identifier for this item.\",\n \"type\": \"string\",\n \"minLength\": 2,\n \"pattern\": \"^[a-zA-Z]+[a-zA-Z0-9_]*$\"\n },\n \"JsonSchemaSchema\": {\n \"id\": \"/JsonSchemaSchema\",\n \"description\": \"A JSON Schema object that describes the expected structure of a JSON value. Validated against JSON Schema Draft 4, 6, or 7 meta-schema (based on the `$schema` field, defaulting to Draft 7) via the validateJsonFieldSchema functional constraint.\",\n \"type\": \"object\",\n \"additionalProperties\": true\n },\n \"PlainInputFieldSchema\": {\n \"description\": \"Field schema specialized for input fields. In addition to the requirements below, the following keys are mutually exclusive:\\n\\n* `children` & `list`\\n* `children` & `dict`\\n* `children` & `type`\\n* `children` & `placeholder`\\n* `children` & `helpText`\\n* `children` & `default`\\n* `dict` & `list`\\n* `dynamic` & `dict`\\n* `dynamic` & `choices`\",\n \"id\": \"/PlainInputFieldSchema\",\n \"type\": \"object\",\n \"required\": [\n \"key\"\n ],\n \"properties\": {\n \"key\": {\n \"description\": \"A unique machine readable key for this value (IE: \\\"fname\\\").\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"label\": {\n \"description\": \"A human readable label for this value (IE: \\\"First Name\\\").\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"type\": {\n \"description\": \"The type of this value. Use `string` for basic text input, `text` for a large, `<textarea>` style box, and `code` for a `<textarea>` with a fixed-width font. Field type of `file` will accept either a file object or a string. If a URL is provided in the string, Zapier will automatically make a GET for that file. Otherwise, a .txt file will be generated.\",\n \"type\": \"string\",\n \"enum\": [\n \"string\",\n \"text\",\n \"integer\",\n \"number\",\n \"boolean\",\n \"datetime\",\n \"file\",\n \"password\",\n \"copy\",\n \"code\",\n \"json\"\n ]\n },\n \"required\": {\n \"description\": \"If this value is required or not.\",\n \"type\": \"boolean\"\n },\n \"default\": {\n \"description\": \"A default value that is saved the first time a Zap is created.\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"list\": {\n \"description\": \"Acts differently when used in inputFields vs. when used in outputFields. In inputFields: Can a user provide multiples of this field? In outputFields: Does this field return an array of items of type `type`?\",\n \"type\": \"boolean\"\n },\n \"children\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"/PlainInputFieldSchema\"\n },\n \"description\": \"An array of child fields that define the structure of a sub-object for this field. Usually used for line items.\",\n \"minItems\": 1\n },\n \"dict\": {\n \"description\": \"Is this field a key/value input?\",\n \"type\": \"boolean\"\n },\n \"helpText\": {\n \"description\": \"A human readable description of this value (IE: \\\"The first part of a full name.\\\"). You can use Markdown.\",\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 1000\n },\n \"search\": {\n \"description\": \"A reference to a search that will guide the user to add a search step to populate this field when creating a Zap.\",\n \"$ref\": \"/RefResourceSchema\"\n },\n \"dynamic\": {\n \"description\": \"A reference to a trigger that will power a dynamic dropdown.\",\n \"$ref\": \"/RefResourceSchema\"\n },\n \"dependsOn\": {\n \"description\": \"Specifies which other input fields this field depends on. These must be filled before this one becomes enabled, and when their values change, this field's value should be cleared.\",\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"resource\": {\n \"description\": \"Explicitly links this input field to a resource. Use the resource key (e.g., \\\"spreadsheet\\\") or dot notation for resource fields (e.g., \\\"spreadsheet.url\\\"). If not set for dynamic dropdowns, the resource is derived implicitly from the `dynamic` property.\",\n \"type\": \"string\",\n \"minLength\": 1,\n \"pattern\": \"^[a-zA-Z0-9_]+(\\\\.[a-zA-Z0-9_]+)?$\"\n },\n \"choices\": {\n \"description\": \"Describes how to populate this dropdown. Can be a static list or a dynamic object with pagination and search support.\",\n \"oneOf\": [\n {\n \"$ref\": \"/FieldChoicesSchema\"\n },\n {\n \"$ref\": \"/FieldDynamicChoicesSchema\"\n }\n ]\n },\n \"placeholder\": {\n \"description\": \"An example value that is not saved.\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"altersDynamicFields\": {\n \"description\": \"Does the value of this field affect the definitions of other fields in the set?\",\n \"type\": \"boolean\"\n },\n \"computed\": {\n \"description\": \"Is this field automatically populated (and hidden from the user)? Note: Only OAuth, Session Auth, and certain internal use cases support fields with this key.\",\n \"type\": \"boolean\"\n },\n \"inputFormat\": {\n \"description\": \"Useful when you expect the input to be part of a longer string. Put \\\"{{input}}\\\" in place of the user's input (IE: \\\"https://{{input}}.yourdomain.com\\\").\",\n \"type\": \"string\",\n \"pattern\": \"^.*{{input}}.*$\"\n },\n \"meta\": {\n \"description\": \"Allows for additional metadata to be stored on the field. Supports simple key-values only (no sub-objects or arrays).\",\n \"$ref\": \"/FieldMetaSchema\"\n },\n \"group\": {\n \"description\": \"References a group key from the operation's inputFieldGroups to organize this field with others.\",\n \"$ref\": \"/KeySchema\"\n },\n \"schema\": {\n \"description\": \"A JSON Schema object that describes the expected structure of the JSON value. Only valid when `type` is `json`.\",\n \"$ref\": \"/JsonSchemaSchema\"\n }\n },\n \"additionalProperties\": false\n },\n \"InputFieldGroupSchema\": {\n \"id\": \"/InputFieldGroupSchema\",\n \"description\": \"Object for visual grouping of input fields.\",\n \"type\": \"object\",\n \"required\": [\n \"key\"\n ],\n \"properties\": {\n \"key\": {\n \"description\": \"The unique identifier for this group.\",\n \"$ref\": \"/KeySchema\"\n },\n \"label\": {\n \"description\": \"The human-readable name for the group.\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"emphasize\": {\n \"description\": \"Whether this group should be visually emphasized in the UI.\",\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n },\n \"PlainOutputFieldSchema\": {\n \"description\": \"Field schema specialized for output fields. In addition to the requirements below, the following keys are mutually exclusive:\\n\\n* `children` & `list`\\n* `children` & `dict`\\n* `children` & `type`\\n* `children` & `placeholder`\\n* `children` & `helpText`\\n* `children` & `default`\\n* `dict` & `list`\\n* `dynamic` & `dict`\\n* `dynamic` & `choices`\",\n \"id\": \"/PlainOutputFieldSchema\",\n \"type\": \"object\",\n \"required\": [\n \"key\"\n ],\n \"properties\": {\n \"key\": {\n \"description\": \"A unique machine readable key for this value (IE: \\\"fname\\\").\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"label\": {\n \"description\": \"A human readable label for this value (IE: \\\"First Name\\\").\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"type\": {\n \"description\": \"The type of this value. Field type of `file` will accept either a file object or a string. If a URL is provided in the string, Zapier will automatically make a GET for that file. Otherwise, a .txt file will be generated.\",\n \"type\": \"string\",\n \"enum\": [\n \"string\",\n \"number\",\n \"boolean\",\n \"datetime\",\n \"file\",\n \"password\",\n \"integer\"\n ]\n },\n \"required\": {\n \"description\": \"If this value is required or not.\",\n \"type\": \"boolean\"\n },\n \"default\": {\n \"description\": \"A default value that is saved the first time a Zap is created.\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"list\": {\n \"description\": \"Acts differently when used in inputFields vs. when used in outputFields. In inputFields: Can a user provide multiples of this field? In outputFields: Does this field return an array of items of type `type`?\",\n \"type\": \"boolean\"\n },\n \"children\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"/PlainOutputFieldSchema\"\n },\n \"description\": \"An array of child fields that define the structure of a sub-object for this field. Usually used for line items.\",\n \"minItems\": 1\n },\n \"dict\": {\n \"description\": \"Is this field a key/value input?\",\n \"type\": \"boolean\"\n },\n \"primary\": {\n \"description\": \"Use this field as part of the primary key for deduplication. You can set multiple fields as \\\"primary\\\", provided they are unique together. If no fields are set, Zapier will default to using the `id` field. `primary` only makes sense for `outputFields`. It only works in static `outputFields`; will not work in custom/dynamic `outputFields`. For more information, see [How deduplication works in Zapier](https://platform.zapier.com/build/deduplication).\",\n \"type\": \"boolean\"\n },\n \"steadyState\": {\n \"description\": \"Prevents triggering on new output until all values for fields with this property remain unchanged for 2 polls. It can be used to, e.g., not trigger on a new contact until the contact has completed typing their name. NOTE that this only applies to the `outputFields` of polling triggers.\",\n \"type\": \"boolean\"\n },\n \"sample\": {\n \"description\": \"An example value for this field. Can be any type (string, number, boolean, object, array, null) to match the expected field output. Values provided here will be combined with values in the operation level `sample` field, with this field taking precedence. This is most useful when using a function to generate dynamic `outputFields`.\",\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"number\"\n },\n {\n \"type\": \"boolean\"\n },\n {\n \"type\": \"object\"\n },\n {\n \"type\": \"array\"\n },\n {\n \"type\": \"null\"\n }\n ]\n }\n },\n \"additionalProperties\": false\n },\n \"ThrottleOverrideObjectSchema\": {\n \"id\": \"/ThrottleOverrideObjectSchema\",\n \"description\": \"EXPERIMENTAL: Overrides the original throttle configuration based on a Zapier account attribute.\",\n \"type\": \"object\",\n \"required\": [\n \"window\",\n \"limit\",\n \"filter\"\n ],\n \"properties\": {\n \"window\": {\n \"description\": \"The timeframe, in seconds, within which the system tracks the number of invocations for an action. The number of invocations begins at zero at the start of each window.\",\n \"type\": \"integer\"\n },\n \"limit\": {\n \"description\": \"The maximum number of invocations for an action, allowed within the timeframe window.\",\n \"type\": \"integer\"\n },\n \"filter\": {\n \"description\": \"Account-based attribute to override the throttle by. You can set to one of the following: \\\"free\\\", \\\"trial\\\", \\\"paid\\\". Therefore, the throttle scope would be automatically set to \\\"account\\\" and ONLY the accounts based on the specified filter will have their requests throttled based on the throttle overrides while the rest are throttled based on the original configuration.\",\n \"type\": \"string\",\n \"enum\": [\n \"free\",\n \"trial\",\n \"paid\"\n ]\n },\n \"retry\": {\n \"description\": \"The effect of throttling on the tasks of the action. `true` means throttled tasks are automatically retried after some delay, while `false` means tasks are held without retry. It defaults to `true`. NOTE that it has no effect on polling triggers and should not be set.\",\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n },\n \"InputFieldsSchema\": {\n \"id\": \"/InputFieldsSchema\",\n \"description\": \"An array or collection of input fields.\",\n \"type\": \"array\",\n \"items\": {\n \"oneOf\": [\n {\n \"$ref\": \"/PlainInputFieldSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n }\n },\n \"InputFieldGroupsSchema\": {\n \"id\": \"/InputFieldGroupsSchema\",\n \"description\": \"An array or collection of input field groups.\",\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"/InputFieldGroupSchema\"\n },\n \"additionalProperties\": false\n },\n \"OutputFieldsSchema\": {\n \"id\": \"/OutputFieldsSchema\",\n \"description\": \"An array or collection of output fields.\",\n \"type\": \"array\",\n \"items\": {\n \"oneOf\": [\n {\n \"$ref\": \"/PlainOutputFieldSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n }\n },\n \"LockObjectSchema\": {\n \"id\": \"/LockObjectSchema\",\n \"description\": \"Zapier uses this configuration to ensure this action is performed one at a time per scope (avoid concurrency).\",\n \"type\": \"object\",\n \"required\": [\n \"key\"\n ],\n \"properties\": {\n \"key\": {\n \"description\": \"The key to use for locking. This should be unique to the operation. While actions of different integrations with the same key and scope will never lock each other out, actions of the same integration with the same key and scope will do. User data provided for the input fields can be used in the key with the use of the curly braces referencing. For example, to access the user data provided for the input field \\\"test_field\\\", use `{{bundle.inputData.test_field}}`. Note that a required input field should be referenced to get user data always.\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"scope\": {\n \"description\": \"By default, locks are scoped to the app. That is, all users of the app will share the same locks. If you want to restrict serial access to a specific user, auth, or account, you can set the scope to one or more of the following: 'user' - Locks based on user ids. 'auth' - Locks based on unique auth ids. 'account' - Locks for all users under a single account. You may also combine scopes. Note that \\\"app\\\" is included, always, in the scope provided. For example, a scope of ['account', 'auth'] would result to ['app', 'account', 'auth'].\",\n \"type\": \"array\",\n \"items\": {\n \"enum\": [\n \"user\",\n \"auth\",\n \"account\"\n ],\n \"type\": \"string\"\n }\n },\n \"timeout\": {\n \"description\": \"The number of seconds to hold the lock before releasing it to become accessible to other task invokes that need it. If not provided, the default set by the app will be used. It cannot be more than 180.\",\n \"type\": \"integer\"\n }\n },\n \"additionalProperties\": false\n },\n \"ResultsSchema\": {\n \"id\": \"/ResultsSchema\",\n \"description\": \"An array of objects suitable for returning in perform calls.\",\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"minProperties\": 1\n }\n },\n \"ThrottleObjectSchema\": {\n \"id\": \"/ThrottleObjectSchema\",\n \"description\": \"Zapier uses this configuration to apply throttling when the limit for the window is exceeded. **NOTE:** The final key used for the throttling is formed as a combination of all the configurations; key, window, limit, and scope. To share a limit across multiple actions in an integration, each should have the same configuration set without \\\"action\\\" in the scope.\",\n \"type\": \"object\",\n \"required\": [\n \"window\",\n \"limit\"\n ],\n \"properties\": {\n \"window\": {\n \"description\": \"The timeframe, in seconds, within which the system tracks the number of invocations for an action. The number of invocations begins at zero at the start of each window.\",\n \"type\": \"integer\"\n },\n \"limit\": {\n \"description\": \"The maximum number of invocations for an action, allowed within the timeframe window.\",\n \"type\": \"integer\"\n },\n \"key\": {\n \"description\": \"The key to throttle with in combination with the scope. User data provided for the input fields can be used in the key with the use of the curly braces referencing. For example, to access the user data provided for the input field \\\"test_field\\\", use `{{bundle.inputData.test_field}}`. Note that a required input field should be referenced to get user data always.\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"scope\": {\n \"description\": \"The granularity to throttle by. You can set the scope to one or more of the following: 'user' - Throttles based on user ids. 'auth' - Throttles based on auth ids. 'account' - Throttles based on account ids for all users under a single account. 'action' - Throttles the action it is set on separately from other actions. By default, throttling is scoped to the action and account.\",\n \"type\": \"array\",\n \"items\": {\n \"enum\": [\n \"user\",\n \"auth\",\n \"account\",\n \"action\"\n ],\n \"type\": \"string\"\n }\n },\n \"retry\": {\n \"description\": \"The effect of throttling on the tasks of the action. `true` means throttled tasks are automatically retried after some delay, while `false` means tasks are held without retry. It defaults to `true`. NOTE that it has no effect on polling triggers and should not be set.\",\n \"type\": \"boolean\"\n },\n \"filter\": {\n \"description\": \"EXPERIMENTAL: Account-based attribute to override the throttle by. You can set to one of the following: \\\"free\\\", \\\"trial\\\", \\\"paid\\\". Therefore, the throttle scope would be automatically set to \\\"account\\\" and ONLY the accounts based on the specified filter will have their requests throttled based on the throttle overrides while the rest are throttled based on the original configuration.\",\n \"type\": \"string\",\n \"enum\": [\n \"free\",\n \"trial\",\n \"paid\"\n ]\n },\n \"overrides\": {\n \"description\": \"EXPERIMENTAL: Overrides the original throttle configuration based on a Zapier account attribute.\",\n \"type\": \"array\",\n \"minItems\": 1,\n \"items\": {\n \"$ref\": \"/ThrottleOverrideObjectSchema\"\n }\n }\n },\n \"additionalProperties\": false\n },\n \"BasicDisplaySchema\": {\n \"id\": \"/BasicDisplaySchema\",\n \"description\": \"Represents user information for a trigger, search, or create.\",\n \"type\": \"object\",\n \"properties\": {\n \"label\": {\n \"description\": \"A short label like \\\"New Record\\\" or \\\"Create Record in Project\\\". Optional if `hidden` is true.\",\n \"type\": \"string\",\n \"minLength\": 2,\n \"maxLength\": 64,\n \"docAnnotation\": {\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"**yes** (with exceptions, see description)\"\n }\n }\n },\n \"description\": {\n \"description\": \"A description of what this trigger, search, or create does. Optional if `hidden` is true.\",\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 1000,\n \"docAnnotation\": {\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"**yes** (with exceptions, see description)\"\n }\n }\n },\n \"directions\": {\n \"description\": \"A short blurb that can explain how to get this working. EG: how and where to copy-paste a static hook URL into your application. Only evaluated for static webhooks.\",\n \"type\": \"string\",\n \"minLength\": 12,\n \"maxLength\": 1000\n },\n \"hidden\": {\n \"description\": \"Should this operation be unselectable by users?\",\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n },\n \"BasicOperationSchema\": {\n \"id\": \"/BasicOperationSchema\",\n \"description\": \"Represents the fundamental mechanics of triggers, searches, or creates.\",\n \"type\": \"object\",\n \"required\": [\n \"perform\"\n ],\n \"properties\": {\n \"resource\": {\n \"description\": \"Optionally reference and extends a resource. Allows Zapier to automatically tie together samples, lists and hooks, greatly improving the UX. EG: if you had another trigger reusing a resource but filtering the results.\",\n \"$ref\": \"/KeySchema\"\n },\n \"perform\": {\n \"description\": \"How will Zapier get the data? This can be a function like `(z) => [{id: 123}]` or a request like `{url: 'http...'}`.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"inputFields\": {\n \"description\": \"What should the form a user sees and configures look like?\",\n \"$ref\": \"/InputFieldsSchema\"\n },\n \"inputFieldGroups\": {\n \"description\": \"Defines groups for organizing input fields in the UI. Each group can have a key, label, and emphasis styling.\",\n \"$ref\": \"/InputFieldGroupsSchema\"\n },\n \"outputFields\": {\n \"description\": \"What fields of data will this return? Will use resource outputFields if missing, will also use sample if available.\",\n \"$ref\": \"/OutputFieldsSchema\"\n },\n \"sample\": {\n \"description\": \"What does a sample of data look like? Will use resource sample if missing. Requirement waived if `display.hidden` is true or if this belongs to a resource that has a top-level sample\",\n \"type\": \"object\",\n \"minProperties\": 1,\n \"docAnnotation\": {\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"**yes** (with exceptions, see description)\"\n }\n }\n },\n \"lock\": {\n \"description\": \"Zapier uses this configuration to ensure this action is performed one at a time per scope (avoid concurrency).\",\n \"$ref\": \"/LockObjectSchema\"\n },\n \"throttle\": {\n \"description\": \"Zapier uses this configuration to apply throttling when the limit for the window is exceeded.\",\n \"$ref\": \"/ThrottleObjectSchema\"\n },\n \"cleanInputData\": {\n \"description\": \"If true, Zapier removes empty strings, `null`, `undefined`, and empty Arrays or objects from `bundle.inputData` recursively before passing it to your `perform*` function. If you want to handle empty values yourself in your code, explicitly set this to false. There is also a global flag with the same name in `App.flags`. This one takes precedence over the global one.\",\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n },\n \"BasicHookOperationSchema\": {\n \"id\": \"/BasicHookOperationSchema\",\n \"description\": \"Represents the inbound mechanics of hooks with optional subscribe/unsubscribe. Defers to list for fields.\",\n \"type\": \"object\",\n \"required\": [\n \"perform\"\n ],\n \"properties\": {\n \"type\": {\n \"description\": \"Must be explicitly set to `\\\"hook\\\"` unless this hook is defined as part of a resource, in which case it's optional.\",\n \"type\": \"string\",\n \"enum\": [\n \"hook\"\n ],\n \"docAnnotation\": {\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"**yes** (with exceptions, see description)\"\n }\n }\n },\n \"resource\": {\n \"description\": \"Optionally reference and extends a resource. Allows Zapier to automatically tie together samples, lists and hooks, greatly improving the UX. EG: if you had another trigger reusing a resource but filtering the results.\",\n \"$ref\": \"/KeySchema\"\n },\n \"perform\": {\n \"description\": \"A function that processes the inbound webhook request.\",\n \"$ref\": \"/FunctionSchema\"\n },\n \"performList\": {\n \"description\": \"Fetch a list of items on demand during testing instead of waiting for a hook. You can also consider resources and their built-in hook/list methods. Note: this is required for public apps to ensure the best UX for the end-user. For private apps, this is strongly recommended for testing REST Hooks. Otherwise, you can ignore warnings about this property with the `--without-style` flag during `zapier-platform push`.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ],\n \"docAnnotation\": {\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"**yes** (with exceptions, see description)\"\n }\n }\n },\n \"canPaginate\": {\n \"description\": \"Does this endpoint support pagination via temporary cursor storage?\",\n \"type\": \"boolean\"\n },\n \"performSubscribe\": {\n \"description\": \"Takes a URL and any necessary data from the user and subscribes. Note: this is required for public apps to ensure the best UX for the end-user. For private apps, this is strongly recommended for testing REST Hooks. Otherwise, you can ignore warnings about this property with the `--without-style` flag during `zapier-platform push`.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ],\n \"docAnnotation\": {\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"**yes** (with exceptions, see description)\"\n }\n }\n },\n \"performUnsubscribe\": {\n \"description\": \"Takes a URL and data from a previous subscribe call and unsubscribes. Note: this is required for public apps to ensure the best UX for the end-user. For private apps, this is strongly recommended for testing REST Hooks. Otherwise, you can ignore warnings about this property with the `--without-style` flag during `zapier-platform push`.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ],\n \"docAnnotation\": {\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"**yes** (with exceptions, see description)\"\n }\n }\n },\n \"inputFields\": {\n \"description\": \"What should the form a user sees and configures look like?\",\n \"$ref\": \"/InputFieldsSchema\"\n },\n \"inputFieldGroups\": {\n \"description\": \"Defines groups for organizing input fields in the UI. Each group can have a key, label, and emphasis styling.\",\n \"$ref\": \"/InputFieldGroupsSchema\"\n },\n \"outputFields\": {\n \"description\": \"What fields of data will this return? Will use resource outputFields if missing, will also use sample if available.\",\n \"$ref\": \"/OutputFieldsSchema\"\n },\n \"sample\": {\n \"description\": \"What does a sample of data look like? Will use resource sample if missing. Requirement waived if `display.hidden` is true or if this belongs to a resource that has a top-level sample\",\n \"type\": \"object\",\n \"minProperties\": 1,\n \"docAnnotation\": {\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"**yes** (with exceptions, see description)\"\n }\n }\n },\n \"cleanInputData\": {\n \"description\": \"If true, Zapier removes empty strings, `null`, `undefined`, and empty Arrays or objects from `bundle.inputData` recursively before passing it to your `perform*` function. If you want to handle empty values yourself in your code, explicitly set this to false. There is also a global flag with the same name in `App.flags`. This one takes precedence over the global one.\",\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n },\n \"BasicPollingOperationSchema\": {\n \"id\": \"/BasicPollingOperationSchema\",\n \"description\": \"Represents the fundamental mechanics of a trigger.\",\n \"type\": \"object\",\n \"required\": [\n \"perform\"\n ],\n \"properties\": {\n \"type\": {\n \"description\": \"Clarify how this operation works (polling == pull or hook == push).\",\n \"type\": \"string\",\n \"default\": \"polling\",\n \"enum\": [\n \"polling\"\n ]\n },\n \"resource\": {\n \"description\": \"Optionally reference and extends a resource. Allows Zapier to automatically tie together samples, lists and hooks, greatly improving the UX. EG: if you had another trigger reusing a resource but filtering the results.\",\n \"$ref\": \"/KeySchema\"\n },\n \"perform\": {\n \"description\": \"How will Zapier get the data? This can be a function like `(z) => [{id: 123}]` or a request like `{url: 'http...'}`.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"canPaginate\": {\n \"description\": \"Does this endpoint support pagination via temporary cursor storage?\",\n \"type\": \"boolean\"\n },\n \"inputFields\": {\n \"description\": \"What should the form a user sees and configures look like?\",\n \"$ref\": \"/InputFieldsSchema\"\n },\n \"inputFieldGroups\": {\n \"description\": \"Defines groups for organizing input fields in the UI. Each group can have a key, label, and emphasis styling.\",\n \"$ref\": \"/InputFieldGroupsSchema\"\n },\n \"outputFields\": {\n \"description\": \"What fields of data will this return? Will use resource outputFields if missing, will also use sample if available.\",\n \"$ref\": \"/OutputFieldsSchema\"\n },\n \"sample\": {\n \"description\": \"What does a sample of data look like? Will use resource sample if missing. Requirement waived if `display.hidden` is true or if this belongs to a resource that has a top-level sample\",\n \"type\": \"object\",\n \"minProperties\": 1,\n \"docAnnotation\": {\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"**yes** (with exceptions, see description)\"\n }\n }\n },\n \"throttle\": {\n \"description\": \"Zapier uses this configuration to apply throttling when the limit for the window is exceeded.\",\n \"$ref\": \"/ThrottleObjectSchema\"\n },\n \"cleanInputData\": {\n \"description\": \"If true, Zapier removes empty strings, `null`, `undefined`, and empty Arrays or objects from `bundle.inputData` recursively before passing it to your `perform*` function. If you want to handle empty values yourself in your code, explicitly set this to false. There is also a global flag with the same name in `App.flags`. This one takes precedence over the global one.\",\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n },\n \"BasicActionOperationSchema\": {\n \"id\": \"/BasicActionOperationSchema\",\n \"description\": \"Represents the fundamental mechanics of a search/create.\",\n \"type\": \"object\",\n \"required\": [\n \"perform\"\n ],\n \"properties\": {\n \"resource\": {\n \"description\": \"Optionally reference and extends a resource. Allows Zapier to automatically tie together samples, lists and hooks, greatly improving the UX. EG: if you had another trigger reusing a resource but filtering the results.\",\n \"$ref\": \"/KeySchema\"\n },\n \"perform\": {\n \"description\": \"How will Zapier get the data? This can be a function like `(z) => [{id: 123}]` or a request like `{url: 'http...'}`.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"performResume\": {\n \"description\": \"A function that parses data from a perform (which uses z.generateCallbackUrl()) and callback request to resume this action.\",\n \"$ref\": \"/FunctionSchema\"\n },\n \"performGet\": {\n \"description\": \"How will Zapier get a single record? If you find yourself reaching for this - consider resources and their built-in get methods.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"inputFields\": {\n \"description\": \"What should the form a user sees and configures look like?\",\n \"$ref\": \"/InputFieldsSchema\"\n },\n \"inputFieldGroups\": {\n \"description\": \"Defines groups for organizing input fields in the UI. Each group can have a key, label, and emphasis styling.\",\n \"$ref\": \"/InputFieldGroupsSchema\"\n },\n \"outputFields\": {\n \"description\": \"What fields of data will this return? Will use resource outputFields if missing, will also use sample if available.\",\n \"$ref\": \"/OutputFieldsSchema\"\n },\n \"sample\": {\n \"description\": \"What does a sample of data look like? Will use resource sample if missing. Requirement waived if `display.hidden` is true or if this belongs to a resource that has a top-level sample\",\n \"type\": \"object\",\n \"minProperties\": 1,\n \"docAnnotation\": {\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"**yes** (with exceptions, see description)\"\n }\n }\n },\n \"lock\": {\n \"description\": \"Zapier uses this configuration to ensure this action is performed one at a time per scope (avoid concurrency).\",\n \"$ref\": \"/LockObjectSchema\"\n },\n \"throttle\": {\n \"description\": \"Zapier uses this configuration to apply throttling when the limit for the window is exceeded.\",\n \"$ref\": \"/ThrottleObjectSchema\"\n },\n \"cleanInputData\": {\n \"description\": \"If true, Zapier removes empty strings, `null`, `undefined`, and empty Arrays or objects from `bundle.inputData` recursively before passing it to your `perform*` function. If you want to handle empty values yourself in your code, explicitly set this to false. There is also a global flag with the same name in `App.flags`. This one takes precedence over the global one.\",\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n },\n \"ResourceMethodGetSchema\": {\n \"id\": \"/ResourceMethodGetSchema\",\n \"description\": \"How will we get a single object given a unique identifier/id?\",\n \"type\": \"object\",\n \"required\": [\n \"display\",\n \"operation\"\n ],\n \"properties\": {\n \"display\": {\n \"description\": \"Define how this get method will be exposed in the UI.\",\n \"$ref\": \"/BasicDisplaySchema\"\n },\n \"operation\": {\n \"description\": \"Define how this get method will work.\",\n \"$ref\": \"/BasicOperationSchema\"\n }\n },\n \"additionalProperties\": false\n },\n \"ResourceMethodHookSchema\": {\n \"id\": \"/ResourceMethodHookSchema\",\n \"description\": \"How will we get notified of new objects? Will be turned into a trigger automatically.\",\n \"type\": \"object\",\n \"required\": [\n \"display\",\n \"operation\"\n ],\n \"properties\": {\n \"display\": {\n \"description\": \"Define how this hook/trigger method will be exposed in the UI.\",\n \"$ref\": \"/BasicDisplaySchema\"\n },\n \"operation\": {\n \"description\": \"Define how this hook/trigger method will work.\",\n \"$ref\": \"/BasicHookOperationSchema\"\n }\n },\n \"additionalProperties\": false\n },\n \"ResourceMethodListSchema\": {\n \"id\": \"/ResourceMethodListSchema\",\n \"description\": \"How will we get a list of new objects? Will be turned into a trigger automatically.\",\n \"type\": \"object\",\n \"required\": [\n \"display\",\n \"operation\"\n ],\n \"properties\": {\n \"display\": {\n \"description\": \"Define how this list/trigger method will be exposed in the UI.\",\n \"$ref\": \"/BasicDisplaySchema\"\n },\n \"operation\": {\n \"description\": \"Define how this list/trigger method will work.\",\n \"$ref\": \"/BasicPollingOperationSchema\"\n }\n },\n \"additionalProperties\": false\n },\n \"ResourceMethodSearchSchema\": {\n \"id\": \"/ResourceMethodSearchSchema\",\n \"description\": \"How will we find a specific object given filters or search terms? Will be turned into a search automatically.\",\n \"type\": \"object\",\n \"required\": [\n \"display\",\n \"operation\"\n ],\n \"properties\": {\n \"display\": {\n \"description\": \"Define how this search method will be exposed in the UI.\",\n \"$ref\": \"/BasicDisplaySchema\"\n },\n \"operation\": {\n \"description\": \"Define how this search method will work.\",\n \"$ref\": \"/BasicActionOperationSchema\"\n }\n },\n \"additionalProperties\": false\n },\n \"ResourceMethodCreateSchema\": {\n \"id\": \"/ResourceMethodCreateSchema\",\n \"description\": \"How will we find create a specific object given inputs? Will be turned into a create automatically.\",\n \"type\": \"object\",\n \"required\": [\n \"display\",\n \"operation\"\n ],\n \"properties\": {\n \"display\": {\n \"description\": \"Define how this create method will be exposed in the UI.\",\n \"$ref\": \"/BasicDisplaySchema\"\n },\n \"operation\": {\n \"description\": \"Define how this create method will work.\",\n \"$ref\": \"/BasicActionOperationSchema\"\n }\n },\n \"additionalProperties\": false\n },\n \"ResourceSchema\": {\n \"id\": \"/ResourceSchema\",\n \"description\": \"Represents a resource, which will in turn power triggers, searches, or creates.\",\n \"type\": \"object\",\n \"required\": [\n \"key\",\n \"noun\"\n ],\n \"properties\": {\n \"key\": {\n \"description\": \"A key to uniquely identify this resource.\",\n \"$ref\": \"/KeySchema\"\n },\n \"noun\": {\n \"description\": \"A noun for this resource that completes the sentence \\\"create a new XXX\\\".\",\n \"type\": \"string\",\n \"minLength\": 2,\n \"maxLength\": 255\n },\n \"get\": {\n \"description\": \"How will we get a single object given a unique identifier/id?\",\n \"$ref\": \"/ResourceMethodGetSchema\"\n },\n \"hook\": {\n \"description\": \"How will we get notified of new objects? Will be turned into a trigger automatically.\",\n \"$ref\": \"/ResourceMethodHookSchema\"\n },\n \"list\": {\n \"description\": \"How will we get a list of new objects? Will be turned into a trigger automatically.\",\n \"$ref\": \"/ResourceMethodListSchema\"\n },\n \"search\": {\n \"description\": \"How will we find a specific object given filters or search terms? Will be turned into a search automatically.\",\n \"$ref\": \"/ResourceMethodSearchSchema\"\n },\n \"create\": {\n \"description\": \"How will we find create a specific object given inputs? Will be turned into a create automatically.\",\n \"$ref\": \"/ResourceMethodCreateSchema\"\n },\n \"outputFields\": {\n \"description\": \"What fields of data will this return?\",\n \"$ref\": \"/OutputFieldsSchema\"\n },\n \"sample\": {\n \"description\": \"What does a sample of data look like?\",\n \"type\": \"object\",\n \"minProperties\": 1\n }\n },\n \"additionalProperties\": false\n },\n \"BulkReadSchema\": {\n \"id\": \"/BulkReadSchema\",\n \"description\": \"How will Zapier fetch resources from your application?\",\n \"type\": \"object\",\n \"required\": [\n \"key\",\n \"noun\",\n \"display\",\n \"operation\"\n ],\n \"properties\": {\n \"key\": {\n \"description\": \"A key to uniquely identify a record.\",\n \"$ref\": \"/KeySchema\"\n },\n \"noun\": {\n \"description\": \"A noun for this read that completes the sentence \\\"reads all of the XXX\\\".\",\n \"type\": \"string\",\n \"minLength\": 2,\n \"maxLength\": 255\n },\n \"display\": {\n \"description\": \"Configures the UI for this read bulk.\",\n \"$ref\": \"/BasicDisplaySchema\"\n },\n \"operation\": {\n \"description\": \"Powers the functionality for this read bulk.\",\n \"$ref\": \"/BasicActionOperationSchema\"\n }\n },\n \"additionalProperties\": false\n },\n \"BasicHookToPollOperationSchema\": {\n \"id\": \"/BasicHookToPollOperationSchema\",\n \"description\": \"Represents the inbound mechanics of hook to poll style triggers. Defers to list for fields.\",\n \"type\": \"object\",\n \"required\": [\n \"performList\",\n \"performSubscribe\",\n \"performUnsubscribe\"\n ],\n \"properties\": {\n \"type\": {\n \"description\": \"Must be explicitly set to `\\\"hook_to_poll\\\"`.\",\n \"type\": \"string\",\n \"enum\": [\n \"hook_to_poll\"\n ],\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"**yes** (with exceptions, see description)\"\n }\n },\n \"performList\": {\n \"description\": \"Similar a polling trigger, but checks for new data when a webhook is received, instead of every few minutes\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"canPaginate\": {\n \"description\": \"Does this endpoint support pagination via temporary cursor storage?\",\n \"type\": \"boolean\"\n },\n \"performSubscribe\": {\n \"description\": \"Takes a URL and any necessary data from the user and subscribes. \",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"performUnsubscribe\": {\n \"description\": \"Takes a URL and data from a previous subscribe call and unsubscribes. \",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"inputFields\": {\n \"description\": \"What should the form a user sees and configures look like?\",\n \"$ref\": \"/InputFieldsSchema\"\n },\n \"inputFieldGroups\": {\n \"description\": \"Defines groups for organizing input fields in the UI. Each group can have a key, label, and emphasis styling.\",\n \"$ref\": \"/InputFieldGroupsSchema\"\n },\n \"outputFields\": {\n \"description\": \"What fields of data will this return? Will use resource outputFields if missing, will also use sample if available.\",\n \"$ref\": \"/OutputFieldsSchema\"\n },\n \"sample\": {\n \"description\": \"What does a sample of data look like? Will use resource sample if missing. Requirement waived if `display.hidden` is true or if this belongs to a resource that has a top-level sample\",\n \"type\": \"object\",\n \"minProperties\": 1,\n \"docAnnotation\": {\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"**yes** (with exceptions, see description)\"\n }\n }\n },\n \"cleanInputData\": {\n \"description\": \"If true, Zapier removes empty strings, `null`, `undefined`, and empty Arrays or objects from `bundle.inputData` recursively before passing it to your `perform*` function. If you want to handle empty values yourself in your code, explicitly set this to false. There is also a global flag with the same name in `App.flags`. This one takes precedence over the global one.\",\n \"type\": \"boolean\"\n },\n \"maxPollingDelay\": {\n \"description\": \"The maximum amount of time to wait between polling requests in seconds. Minimum value is 20s and will default to 20 if not set, or set to a lower value.\",\n \"type\": \"integer\"\n }\n },\n \"additionalProperties\": false,\n \"docAnnotation\": {\n \"hide\": true\n }\n },\n \"TriggerSchema\": {\n \"id\": \"/TriggerSchema\",\n \"description\": \"How will Zapier get notified of new objects?\",\n \"type\": \"object\",\n \"required\": [\n \"key\",\n \"noun\",\n \"display\",\n \"operation\"\n ],\n \"properties\": {\n \"key\": {\n \"description\": \"A key to uniquely identify this trigger.\",\n \"$ref\": \"/KeySchema\"\n },\n \"noun\": {\n \"description\": \"A noun for this trigger that completes the sentence \\\"triggers on a new XXX\\\".\",\n \"type\": \"string\",\n \"minLength\": 2,\n \"maxLength\": 255\n },\n \"display\": {\n \"description\": \"Configures the UI for this trigger.\",\n \"$ref\": \"/BasicDisplaySchema\"\n },\n \"operation\": {\n \"description\": \"Powers the functionality for this trigger.\",\n \"anyOf\": [\n {\n \"$ref\": \"/BasicPollingOperationSchema\"\n },\n {\n \"$ref\": \"/BasicHookOperationSchema\"\n },\n {\n \"$ref\": \"/BasicHookToPollOperationSchema\"\n }\n ]\n }\n },\n \"additionalProperties\": false\n },\n \"BasicSearchOperationSchema\": {\n \"id\": \"/BasicSearchOperationSchema\",\n \"description\": \"Represents the fundamental mechanics of a search.\",\n \"type\": \"object\",\n \"required\": [\n \"perform\"\n ],\n \"properties\": {\n \"resource\": {\n \"description\": \"Optionally reference and extends a resource. Allows Zapier to automatically tie together samples, lists and hooks, greatly improving the UX. EG: if you had another trigger reusing a resource but filtering the results.\",\n \"$ref\": \"/KeySchema\"\n },\n \"perform\": {\n \"description\": \"How will Zapier get the data? This can be a function like `(z) => [{id: 123}]` or a request like `{url: 'http...'}`.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"performResume\": {\n \"description\": \"A function that parses data from a perform (which uses z.generateCallbackUrl()) and callback request to resume this action.\",\n \"$ref\": \"/FunctionSchema\"\n },\n \"performGet\": {\n \"description\": \"How will Zapier get a single record? If you find yourself reaching for this - consider resources and their built-in get methods.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"canPaginate\": {\n \"description\": \"Does this search support pagination?\",\n \"type\": \"boolean\"\n },\n \"inputFields\": {\n \"description\": \"What should the form a user sees and configures look like?\",\n \"$ref\": \"/InputFieldsSchema\"\n },\n \"inputFieldGroups\": {\n \"description\": \"Defines groups for organizing input fields in the UI. Each group can have a key, label, and emphasis styling.\",\n \"$ref\": \"/InputFieldGroupsSchema\"\n },\n \"outputFields\": {\n \"description\": \"What fields of data will this return? Will use resource outputFields if missing, will also use sample if available.\",\n \"$ref\": \"/OutputFieldsSchema\"\n },\n \"sample\": {\n \"description\": \"What does a sample of data look like? Will use resource sample if missing. Requirement waived if `display.hidden` is true or if this belongs to a resource that has a top-level sample\",\n \"type\": \"object\",\n \"minProperties\": 1,\n \"docAnnotation\": {\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"**yes** (with exceptions, see description)\"\n }\n }\n },\n \"lock\": {\n \"description\": \"Zapier uses this configuration to ensure this action is performed one at a time per scope (avoid concurrency).\",\n \"$ref\": \"/LockObjectSchema\"\n },\n \"throttle\": {\n \"description\": \"Zapier uses this configuration to apply throttling when the limit for the window is exceeded.\",\n \"$ref\": \"/ThrottleObjectSchema\"\n },\n \"cleanInputData\": {\n \"description\": \"If true, Zapier removes empty strings, `null`, `undefined`, and empty Arrays or objects from `bundle.inputData` recursively before passing it to your `perform*` function. If you want to handle empty values yourself in your code, explicitly set this to false. There is also a global flag with the same name in `App.flags`. This one takes precedence over the global one.\",\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n },\n \"SearchSchema\": {\n \"id\": \"/SearchSchema\",\n \"description\": \"How will Zapier search for existing objects?\",\n \"type\": \"object\",\n \"required\": [\n \"key\",\n \"noun\",\n \"display\",\n \"operation\"\n ],\n \"properties\": {\n \"key\": {\n \"description\": \"A key to uniquely identify this search.\",\n \"$ref\": \"/KeySchema\"\n },\n \"noun\": {\n \"description\": \"A noun for this search that completes the sentence \\\"finds a specific XXX\\\".\",\n \"type\": \"string\",\n \"minLength\": 2,\n \"maxLength\": 255\n },\n \"display\": {\n \"description\": \"Configures the UI for this search.\",\n \"$ref\": \"/BasicDisplaySchema\"\n },\n \"operation\": {\n \"description\": \"Powers the functionality for this search.\",\n \"$ref\": \"/BasicSearchOperationSchema\"\n }\n },\n \"additionalProperties\": false\n },\n \"BufferConfigSchema\": {\n \"id\": \"/BufferConfigSchema\",\n \"description\": \"Currently an **internal-only** feature. Zapier uses this configuration for creating objects in bulk.\",\n \"type\": \"object\",\n \"required\": [\n \"groupedBy\",\n \"limit\"\n ],\n \"properties\": {\n \"groupedBy\": {\n \"description\": \"The list of keys of input fields to group bulk-create with. The actual user data provided for the fields will be used during execution. Note that a required input field should be referenced to get user data always.\",\n \"type\": \"array\",\n \"minItems\": 1\n },\n \"limit\": {\n \"description\": \"The maximum number of items to call `performBuffer` with. **Note** that it is capped by the platform to prevent exceeding the [AWS Lambda's request/response payload size quota of 6 MB](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html#function-configuration-deployment-and-execution). Also, the execution is time-bound; we recommend reducing it upon consistent timeout.\",\n \"type\n\n…[truncated]", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "platform", "schema"], "related": [], "meta": {"platform_schema_version": "19.1.0", "schema_count": 65}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:appschema", "kind": "schema_type", "key": "AppSchema", "title": "AppSchema", "summary": "Represents a full app.", "body": "# `AppSchema`\n\n> Represents a full app.\n\n## High-level description\n\nRepresents a full app.\n\n## Internals\n\nJSON Schema id `/AppSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: version, platformVersion\n version: /VersionSchema; // A version identifier for your code.\n platformVersion: /VersionSchema; // A version identifier for the Zapier execution environment.\n beforeApp?: /MiddlewaresSchema; // EXPERIMENTAL: Before the perform method is called on your app, you can modify the execution context.\n afterApp?: /MiddlewaresSchema; // EXPERIMENTAL: After the perform method is called on your app, you can modify the response.\n authentication?: /AuthenticationSchema; // Choose what scheme your API uses for authentication.\n requestTemplate?: /RequestSchema; // Define a request mixin, great for setting custom headers, content-types, etc.\n beforeRequest?: /MiddlewaresSchema; // Before an HTTP request is sent via our `z.request()` client, you can modify it.\n afterResponse?: /MiddlewaresSchema; // After an HTTP response is recieved via our `z.request()` client, you can modify it.\n hydrators?: /HydratorsSchema; // An optional bank of named functions that you can use in `z.hydrate('someName')` to lazily load data.\n resources?: /ResourcesSchema; // All the resources for your app. Zapier will take these and generate the relevent triggers/searches/creates automatically\n triggers?: /TriggersSchema; // All the triggers for your app. You can add your own here, or Zapier will automatically register any from the list/hook m\n bulkReads?: /BulkReadsSchema; // All of the read bulks (GETs) your app exposes to retrieve resources in batches.\n searches?: /SearchesSchema; // All the searches for your app. You can add your own here, or Zapier will automatically register any from the search meth\n creates?: /CreatesSchema; // All the creates for your app. You can add your own here, or Zapier will automatically register any from the create metho\n searchOrCreates?: /SearchOrCreatesSchema; // All the search-or-create combos for your app. You can create your own here, or Zapier will automatically register any fr\n searchAndCreates?: /SearchAndCreatesSchema; // An alias for \"searchOrCreates\".\n flags?: /AppFlagsSchema; // Top-level app options\n throttle?: /ThrottleObjectSchema; // Zapier uses this configuration to apply throttling when the limit for the window is exceeded. When set here, it is the d\n legacy?: object; // **INTERNAL USE ONLY**. Zapier uses this to hold properties from a legacy Web Builder app.\n firehoseWebhooks?: object; // **INTERNAL USE ONLY**. Zapier uses this for internal webhook app configurations.\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/AppSchema\",\n \"description\": \"Represents a full app.\",\n \"type\": \"object\",\n \"required\": [\n \"version\",\n \"platformVersion\"\n ],\n \"properties\": {\n \"version\": {\n \"description\": \"A version identifier for your code.\",\n \"$ref\": \"/VersionSchema\"\n },\n \"platformVersion\": {\n \"description\": \"A version identifier for the Zapier execution environment.\",\n \"$ref\": \"/VersionSchema\"\n },\n \"beforeApp\": {\n \"description\": \"EXPERIMENTAL: Before the perform method is called on your app, you can modify the execution context.\",\n \"$ref\": \"/MiddlewaresSchema\"\n },\n \"afterApp\": {\n \"description\": \"EXPERIMENTAL: After the perform method is called on your app, you can modify the response.\",\n \"$ref\": \"/MiddlewaresSchema\"\n },\n \"authentication\": {\n \"description\": \"Choose what scheme your API uses for authentication.\",\n \"$ref\": \"/AuthenticationSchema\"\n },\n \"requestTemplate\": {\n \"description\": \"Define a request mixin, great for setting custom headers, content-types, etc.\",\n \"$ref\": \"/RequestSchema\"\n },\n \"beforeRequest\": {\n \"description\": \"Before an HTTP request is sent via our `z.request()` client, you can modify it.\",\n \"$ref\": \"/MiddlewaresSchema\"\n },\n \"afterResponse\": {\n \"description\": \"After an HTTP response is recieved via our `z.request()` client, you can modify it.\",\n \"$ref\": \"/MiddlewaresSchema\"\n },\n \"hydrators\": {\n \"description\": \"An optional bank of named functions that you can use in `z.hydrate('someName')` to lazily load data.\",\n \"$ref\": \"/HydratorsSchema\"\n },\n \"resources\": {\n \"description\": \"All the resources for your app. Zapier will take these and generate the relevent triggers/searches/creates automatically.\",\n \"$ref\": \"/ResourcesSchema\"\n },\n \"triggers\": {\n \"description\": \"All the triggers for your app. You can add your own here, or Zapier will automatically register any from the list/hook methods on your resources.\",\n \"$ref\": \"/TriggersSchema\"\n },\n \"bulkReads\": {\n \"description\": \"All of the read bulks (GETs) your app exposes to retrieve resources in batches.\",\n \"$ref\": \"/BulkReadsSchema\"\n },\n \"searches\": {\n \"description\": \"All the searches for your app. You can add your own here, or Zapier will automatically register any from the search method on your resources.\",\n \"$ref\": \"/SearchesSchema\"\n },\n \"creates\": {\n \"description\": \"All the creates for your app. You can add your own here, or Zapier will automatically register any from the create method on your resources.\",\n \"$ref\": \"/CreatesSchema\"\n },\n \"searchOrCreates\": {\n \"description\": \"All the search-or-create combos for your app. You can create your own here, or Zapier will automatically register any from resources that define a search, a create, and a get (or define a searchOrCreate directly). Register non-resource search-or-creates here as well.\",\n \"$ref\": \"/SearchOrCreatesSchema\"\n },\n \"searchAndCreates\": {\n \"description\": \"An alias for \\\"searchOrCreates\\\".\",\n \"$ref\": \"/SearchAndCreatesSchema\"\n },\n \"flags\": {\n \"description\": \"Top-level app options\",\n \"$ref\": \"/AppFlagsSchema\"\n },\n \"throttle\": {\n \"description\": \"Zapier uses this configuration to apply throttling when the limit for the window is exceeded. When set here, it is the default throttle configuration used on each action of the integration. And when set in an action's operation object, it gets overwritten for that action only.\",\n \"$ref\": \"/ThrottleObjectSchema\"\n },\n \"legacy\": {\n \"description\": \"**INTERNAL USE ONLY**. Zapier uses this to hold properties from a legacy Web Builder app.\",\n \"type\": \"object\",\n \"docAnnotation\": {\n \"hide\": true\n }\n },\n \"firehoseWebhooks\": {\n \"description\": \"**INTERNAL USE ONLY**. Zapier uses this for internal webhook app configurations.\",\n \"type\": \"object\",\n \"docAnnotation\": {\n \"hide\": true\n }\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "AppSchema required=[version, platformVersion]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/AppSchema", "required": ["version", "platformVersion"], "properties": ["version", "platformVersion", "beforeApp", "afterApp", "authentication", "requestTemplate", "beforeRequest", "afterResponse", "hydrators", "resources", "triggers", "bulkReads", "searches", "creates", "searchOrCreates", "searchAndCreates", "flags", "throttle", "legacy", "firehoseWebhooks"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:functionrequireschema", "kind": "schema_type", "key": "FunctionRequireSchema", "title": "FunctionRequireSchema", "summary": "A path to a file that might have content like `module.exports = (z, bundle) => [{id: 123}];`.", "body": "# `FunctionRequireSchema`\n\n> A path to a file that might have content like `module.exports = (z, bundle) => [{id: 123}];`.\n\n## High-level description\n\nA path to a file that might have content like `module.exports = (z, bundle) => [{id: 123}];`.\n\n## Internals\n\nJSON Schema id `/FunctionRequireSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: require\n require: string; // \n```\n\n## Schema\n\n```json\n{\n \"id\": \"/FunctionRequireSchema\",\n \"description\": \"A path to a file that might have content like `module.exports = (z, bundle) => [{id: 123}];`.\",\n \"type\": \"object\",\n \"required\": [\n \"require\"\n ],\n \"properties\": {\n \"require\": {\n \"type\": \"string\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "FunctionRequireSchema required=[require]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/FunctionRequireSchema", "required": ["require"], "properties": ["require"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:functionsourceschema", "kind": "schema_type", "key": "FunctionSourceSchema", "title": "FunctionSourceSchema", "summary": "Source code like `{source: \"return 1 + 2\"}` which the system will wrap in a function for you.", "body": "# `FunctionSourceSchema`\n\n> Source code like `{source: \"return 1 + 2\"}` which the system will wrap in a function for you.\n\n## High-level description\n\nSource code like `{source: \"return 1 + 2\"}` which the system will wrap in a function for you.\n\n## Internals\n\nJSON Schema id `/FunctionSourceSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: source\n source: string; // JavaScript code for the function body. This must end with a `return` statement.\n args?: array; // Function signature. Defaults to `['z', 'bundle']` if not specified.\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/FunctionSourceSchema\",\n \"description\": \"Source code like `{source: \\\"return 1 + 2\\\"}` which the system will wrap in a function for you.\",\n \"type\": \"object\",\n \"required\": [\n \"source\"\n ],\n \"properties\": {\n \"source\": {\n \"type\": \"string\",\n \"pattern\": \"return\",\n \"description\": \"JavaScript code for the function body. This must end with a `return` statement.\"\n },\n \"args\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n },\n \"description\": \"Function signature. Defaults to `['z', 'bundle']` if not specified.\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "FunctionSourceSchema required=[source]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/FunctionSourceSchema", "required": ["source"], "properties": ["source", "args"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:flatobjectschema", "kind": "schema_type", "key": "FlatObjectSchema", "title": "FlatObjectSchema", "summary": "An object whose values can only be primitives", "body": "# `FlatObjectSchema`\n\n> An object whose values can only be primitives\n\n## High-level description\n\nAn object whose values can only be primitives\n\n## Internals\n\nJSON Schema id `/FlatObjectSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/FlatObjectSchema\",\n \"description\": \"An object whose values can only be primitives\",\n \"type\": \"object\",\n \"patternProperties\": {\n \"[^\\\\s]+\": {\n \"description\": \"Any key may exist in this flat object as long as its values are simple.\",\n \"anyOf\": [\n {\n \"type\": \"null\"\n },\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"integer\"\n },\n {\n \"type\": \"number\"\n },\n {\n \"type\": \"boolean\"\n }\n ]\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "FlatObjectSchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/FlatObjectSchema", "required": [], "properties": [], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:functionschema", "kind": "schema_type", "key": "FunctionSchema", "title": "FunctionSchema", "summary": "Internal pointer to a function from the original source or the source code itself. Encodes arity and if `arguments` is used in the body. Note - just write normal functions and the system will encode the pointers for you. Or, provide {source: \"return 1 + 2\"} and the system will wrap in a function for you.", "body": "# `FunctionSchema`\n\n> Internal pointer to a function from the original source or the source code itself. Encodes arity and if `arguments` is used in the body. Note - just write normal functions and the system will encode the pointers for you. Or, provide {source: \"return 1 + 2\"} and the system will wrap in a function for you.\n\n## High-level description\n\nInternal pointer to a function from the original source or the source code itself. Encodes arity and if `arguments` is used in the body. Note - just write normal functions and the system will encode the pointers for you. Or, provide {source: \"return 1 + 2\"} and the system will wrap in a function for you.\n\n## Internals\n\nJSON Schema id `/FunctionSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/FunctionSchema\",\n \"description\": \"Internal pointer to a function from the original source or the source code itself. Encodes arity and if `arguments` is used in the body. Note - just write normal functions and the system will encode the pointers for you. Or, provide {source: \\\"return 1 + 2\\\"} and the system will wrap in a function for you.\",\n \"oneOf\": [\n {\n \"type\": \"string\",\n \"pattern\": \"^\\\\$func\\\\$\\\\d+\\\\$[tf]\\\\$$\"\n },\n {\n \"$ref\": \"/FunctionRequireSchema\"\n },\n {\n \"$ref\": \"/FunctionSourceSchema\"\n }\n ]\n}\n```", "usage": "", "signature": "FunctionSchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/FunctionSchema", "required": [], "properties": [], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:fieldchoicewithlabelschema", "kind": "schema_type", "key": "FieldChoiceWithLabelSchema", "title": "FieldChoiceWithLabelSchema", "summary": "An object describing a labeled choice in a static dropdown. Useful if the value a user picks isn't exactly what the zap uses. For instance, when they click on a nickname, but the zap uses the user's full name ([image](https://cdn.zapier.com/storage/photos/8ed01ac5df3a511ce93ed2dc43c7fbbc.png)).", "body": "# `FieldChoiceWithLabelSchema`\n\n> An object describing a labeled choice in a static dropdown. Useful if the value a user picks isn't exactly what the zap uses. For instance, when they click on a nickname, but the zap uses the user's full name ([image](https://cdn.zapier.com/storage/photos/8ed01ac5df3a511ce93ed2dc43c7fbbc.png)).\n\n## High-level description\n\nAn object describing a labeled choice in a static dropdown. Useful if the value a user picks isn't exactly what the zap uses. For instance, when they click on a nickname, but the zap uses the user's full name ([image](https://cdn.zapier.com/storage/photos/8ed01ac5df3a511ce93ed2dc43c7fbbc.png)).\n\n## Internals\n\nJSON Schema id `/FieldChoiceWithLabelSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: value, sample, label\n value: string; // The actual value that is sent into the Zap. This is displayed as light grey text in the editor. Should match sample exac\n sample: string; // A legacy field that is no longer used by the editor, but it is still required for now and should match the value.\n label: string; // A human readable label for this value.\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/FieldChoiceWithLabelSchema\",\n \"description\": \"An object describing a labeled choice in a static dropdown. Useful if the value a user picks isn't exactly what the zap uses. For instance, when they click on a nickname, but the zap uses the user's full name ([image](https://cdn.zapier.com/storage/photos/8ed01ac5df3a511ce93ed2dc43c7fbbc.png)).\",\n \"type\": \"object\",\n \"required\": [\n \"value\",\n \"sample\",\n \"label\"\n ],\n \"properties\": {\n \"value\": {\n \"description\": \"The actual value that is sent into the Zap. This is displayed as light grey text in the editor. Should match sample exactly.\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"sample\": {\n \"description\": \"A legacy field that is no longer used by the editor, but it is still required for now and should match the value.\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"label\": {\n \"description\": \"A human readable label for this value.\",\n \"type\": \"string\",\n \"minLength\": 1\n }\n }\n}\n```", "usage": "", "signature": "FieldChoiceWithLabelSchema required=[value, sample, label]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/FieldChoiceWithLabelSchema", "required": ["value", "sample", "label"], "properties": ["value", "sample", "label"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:fieldchoicesschema", "kind": "schema_type", "key": "FieldChoicesSchema", "title": "FieldChoicesSchema", "summary": "A static dropdown of options. Which you use depends on your order and label requirements:\n\nNeed a Label? | Does Order Matter? | Type to Use\n---|---|---\nYes | No | Object of value -> label\nNo | Yes | Array of Strings\nYes | Yes | Array of [FieldChoiceWithLabel](#fieldchoicewithlabelschema)", "body": "# `FieldChoicesSchema`\n\n> A static dropdown of options. Which you use depends on your order and label requirements:\n\nNeed a Label? | Does Order Matter? | Type to Use\n---|---|---\nYes | No | Object of value -> label\nNo | Yes | Array of Strings\nYes | Yes | Array of [FieldChoiceWithLabel](#fieldchoicewithlabelschema)\n\n## High-level description\n\nA static dropdown of options. Which you use depends on your order and label requirements:\n\nNeed a Label? | Does Order Matter? | Type to Use\n---|---|---\nYes | No | Object of value -> label\nNo | Yes | Array of Strings\nYes | Yes | Array of [FieldChoiceWithLabel](#fieldchoicewithlabelschema)\n\n## Internals\n\nJSON Schema id `/FieldChoicesSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/FieldChoicesSchema\",\n \"description\": \"A static dropdown of options. Which you use depends on your order and label requirements:\\n\\nNeed a Label? | Does Order Matter? | Type to Use\\n---|---|---\\nYes | No | Object of value -> label\\nNo | Yes | Array of Strings\\nYes | Yes | Array of [FieldChoiceWithLabel](#fieldchoicewithlabelschema)\",\n \"oneOf\": [\n {\n \"type\": \"object\",\n \"minProperties\": 1,\n \"not\": {\n \"required\": [\n \"perform\"\n ]\n }\n },\n {\n \"type\": \"array\",\n \"minItems\": 1,\n \"items\": {\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"$ref\": \"/FieldChoiceWithLabelSchema\"\n }\n ]\n }\n }\n ]\n}\n```", "usage": "", "signature": "FieldChoicesSchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/FieldChoicesSchema", "required": [], "properties": [], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:plainfieldschema", "kind": "schema_type", "key": "PlainFieldSchema", "title": "PlainFieldSchema", "summary": "In addition to the requirements below, the following keys are mutually exclusive:\n\n* `children` & `list`\n* `children` & `dict`\n* `children` & `type`\n* `children` & `placeholder`\n* `children` & `helpText`\n* `children` & `default`\n* `dict` & `list`\n* `dynamic` & `dict`\n* `dynamic` & `choices`", "body": "# `PlainFieldSchema`\n\n> In addition to the requirements below, the following keys are mutually exclusive:\n\n* `children` & `list`\n* `children` & `dict`\n* `children` & `type`\n* `children` & `placeholder`\n* `children` & `helpText`\n* `children` & `default`\n* `dict` & `list`\n* `dynamic` & `dict`\n* `dynamic` & `choices`\n\n## High-level description\n\nIn addition to the requirements below, the following keys are mutually exclusive:\n\n* `children` & `list`\n* `children` & `dict`\n* `children` & `type`\n* `children` & `placeholder`\n* `children` & `helpText`\n* `children` & `default`\n* `dict` & `list`\n* `dynamic` & `dict`\n* `dynamic` & `choices`\n\n## Internals\n\nJSON Schema id `/PlainFieldSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: key\n key: string; // A unique machine readable key for this value (IE: \"fname\").\n label?: string; // A human readable label for this value (IE: \"First Name\").\n type?: string; // The type of this value. Use `string` for basic text input, `text` for a large, `<textarea>` style box, and `code` for a \n required?: boolean; // If this value is required or not.\n default?: string; // A default value that is saved the first time a Zap is created.\n list?: boolean; // Acts differently when used in inputFields vs. when used in outputFields. In inputFields: Can a user provide multiples of\n children?: array; // An array of child fields that define the structure of a sub-object for this field. Usually used for line items.\n dict?: boolean; // Is this field a key/value input?\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/PlainFieldSchema\",\n \"description\": \"In addition to the requirements below, the following keys are mutually exclusive:\\n\\n* `children` & `list`\\n* `children` & `dict`\\n* `children` & `type`\\n* `children` & `placeholder`\\n* `children` & `helpText`\\n* `children` & `default`\\n* `dict` & `list`\\n* `dynamic` & `dict`\\n* `dynamic` & `choices`\",\n \"type\": \"object\",\n \"required\": [\n \"key\"\n ],\n \"docAnnotation\": {\n \"hide\": true\n },\n \"properties\": {\n \"key\": {\n \"description\": \"A unique machine readable key for this value (IE: \\\"fname\\\").\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"label\": {\n \"description\": \"A human readable label for this value (IE: \\\"First Name\\\").\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"type\": {\n \"description\": \"The type of this value. Use `string` for basic text input, `text` for a large, `<textarea>` style box, and `code` for a `<textarea>` with a fixed-width font. Field type of `file` will accept either a file object or a string. If a URL is provided in the string, Zapier will automatically make a GET for that file. Otherwise, a .txt file will be generated.\",\n \"type\": \"string\",\n \"enum\": [\n \"string\",\n \"text\",\n \"integer\",\n \"number\",\n \"boolean\",\n \"datetime\",\n \"file\",\n \"password\",\n \"copy\",\n \"code\",\n \"json\"\n ]\n },\n \"required\": {\n \"description\": \"If this value is required or not.\",\n \"type\": \"boolean\"\n },\n \"default\": {\n \"description\": \"A default value that is saved the first time a Zap is created.\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"list\": {\n \"description\": \"Acts differently when used in inputFields vs. when used in outputFields. In inputFields: Can a user provide multiples of this field? In outputFields: Does this field return an array of items of type `type`?\",\n \"type\": \"boolean\"\n },\n \"children\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"/PlainFieldSchema\"\n },\n \"description\": \"An array of child fields that define the structure of a sub-object for this field. Usually used for line items.\",\n \"minItems\": 1\n },\n \"dict\": {\n \"description\": \"Is this field a key/value input?\",\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "PlainFieldSchema required=[key]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/PlainFieldSchema", "required": ["key"], "properties": ["key", "label", "type", "required", "default", "list", "children", "dict"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:authfieldschema", "kind": "schema_type", "key": "AuthFieldSchema", "title": "AuthFieldSchema", "summary": "Field schema specialized for authentication fields. In addition to the requirements below, the following keys are mutually exclusive:\n\n* `children` & `list`\n* `children` & `dict`\n* `children` & `type`\n* `children` & `placeholder`\n* `children` & `helpText`\n* `children` & `default`\n* `dict` & `list`\n* `dynamic` & `dict`\n* `dynamic` & `choices`", "body": "# `AuthFieldSchema`\n\n> Field schema specialized for authentication fields. In addition to the requirements below, the following keys are mutually exclusive:\n\n* `children` & `list`\n* `children` & `dict`\n* `children` & `type`\n* `children` & `placeholder`\n* `children` & `helpText`\n* `children` & `default`\n* `dict` & `list`\n* `dynamic` & `dict`\n* `dynamic` & `choices`\n\n## High-level description\n\nField schema specialized for authentication fields. In addition to the requirements below, the following keys are mutually exclusive:\n\n* `children` & `list`\n* `children` & `dict`\n* `children` & `type`\n* `children` & `placeholder`\n* `children` & `helpText`\n* `children` & `default`\n* `dict` & `list`\n* `dynamic` & `dict`\n* `dynamic` & `choices`\n\n## Internals\n\nJSON Schema id `/AuthFieldSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: key\n key: string; // A unique machine readable key for this value (IE: \"fname\").\n label?: string; // A human readable label for this value (IE: \"First Name\").\n type?: string; // The type of this value used to be.\n required?: boolean; // If this value is required or not. This defaults to `true`.\n default?: string; // A default value that is saved the first time a Zap is created.\n list?: boolean; // Acts differently when used in inputFields vs. when used in outputFields. In inputFields: Can a user provide multiples of\n children?: array; // An array of child fields that define the structure of a sub-object for this field. Usually used for line items.\n dict?: boolean; // Is this field a key/value input?\n helpText?: string; // A human readable description of this value (IE: \"The first part of a full name.\"). You can use Markdown.\n placeholder?: string; // An example value that is not saved.\n choices?: /FieldChoicesSchema; // An object of machine keys and human values to populate a static dropdown.\n computed?: boolean; // Is this field automatically populated (and hidden from the user)? Note: Only OAuth and Session Auth support fields with \n inputFormat?: string; // Useful when you expect the input to be part of a longer string. Put \"{{input}}\" in place of the user's input (IE: \"https\n isNoSecret?: boolean; // Indicates if this authentication field is safe to e.g. be stored without encryption or displayed (not a secret).\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/AuthFieldSchema\",\n \"description\": \"Field schema specialized for authentication fields. In addition to the requirements below, the following keys are mutually exclusive:\\n\\n* `children` & `list`\\n* `children` & `dict`\\n* `children` & `type`\\n* `children` & `placeholder`\\n* `children` & `helpText`\\n* `children` & `default`\\n* `dict` & `list`\\n* `dynamic` & `dict`\\n* `dynamic` & `choices`\",\n \"required\": [\n \"key\"\n ],\n \"type\": \"object\",\n \"properties\": {\n \"key\": {\n \"description\": \"A unique machine readable key for this value (IE: \\\"fname\\\").\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"label\": {\n \"description\": \"A human readable label for this value (IE: \\\"First Name\\\").\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"type\": {\n \"description\": \"The type of this value used to be.\",\n \"type\": \"string\",\n \"enum\": [\n \"string\",\n \"number\",\n \"boolean\",\n \"datetime\",\n \"copy\",\n \"password\",\n \"integer\",\n \"text\"\n ]\n },\n \"required\": {\n \"description\": \"If this value is required or not. This defaults to `true`.\",\n \"type\": \"boolean\"\n },\n \"default\": {\n \"description\": \"A default value that is saved the first time a Zap is created.\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"list\": {\n \"description\": \"Acts differently when used in inputFields vs. when used in outputFields. In inputFields: Can a user provide multiples of this field? In outputFields: Does this field return an array of items of type `type`?\",\n \"type\": \"boolean\"\n },\n \"children\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"/AuthFieldSchema\"\n },\n \"description\": \"An array of child fields that define the structure of a sub-object for this field. Usually used for line items.\",\n \"minItems\": 1\n },\n \"dict\": {\n \"description\": \"Is this field a key/value input?\",\n \"type\": \"boolean\"\n },\n \"helpText\": {\n \"description\": \"A human readable description of this value (IE: \\\"The first part of a full name.\\\"). You can use Markdown.\",\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 1000\n },\n \"placeholder\": {\n \"description\": \"An example value that is not saved.\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"choices\": {\n \"description\": \"An object of machine keys and human values to populate a static dropdown.\",\n \"$ref\": \"/FieldChoicesSchema\"\n },\n \"computed\": {\n \"description\": \"Is this field automatically populated (and hidden from the user)? Note: Only OAuth and Session Auth support fields with this key.\",\n \"type\": \"boolean\"\n },\n \"inputFormat\": {\n \"description\": \"Useful when you expect the input to be part of a longer string. Put \\\"{{input}}\\\" in place of the user's input (IE: \\\"https://{{input}}.yourdomain.com\\\").\",\n \"type\": \"string\",\n \"pattern\": \"^.*{{input}}.*$\"\n },\n \"isNoSecret\": {\n \"description\": \"Indicates if this authentication field is safe to e.g. be stored without encryption or displayed (not a secret).\",\n \"type\": \"boolean\"\n }\n }\n}\n```", "usage": "", "signature": "AuthFieldSchema required=[key]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/AuthFieldSchema", "required": ["key"], "properties": ["key", "label", "type", "required", "default", "list", "children", "dict", "helpText", "placeholder", "choices", "computed", "inputFormat", "isNoSecret"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:requestschema", "kind": "schema_type", "key": "RequestSchema", "title": "RequestSchema", "summary": "A representation of a HTTP request - you can use the `{{syntax}}` to inject authentication, field or global variables.", "body": "# `RequestSchema`\n\n> A representation of a HTTP request - you can use the `{{syntax}}` to inject authentication, field or global variables.\n\n## High-level description\n\nA representation of a HTTP request - you can use the `{{syntax}}` to inject authentication, field or global variables.\n\n## Internals\n\nJSON Schema id `/RequestSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n method?: string; // The HTTP method for the request.\n url?: string; // A URL for the request (we will parse the querystring and merge with params). Keys and values will not be re-encoded.\n body?: any; // Can be nothing, a raw string or JSON (object or array).\n params?: /FlatObjectSchema; // A mapping of the querystring - will get merged with any query params in the URL. Keys and values will be encoded.\n headers?: /FlatObjectSchema; // The HTTP headers for the request.\n auth?: any; // An object holding the auth parameters for OAuth1 request signing, like `{oauth_token: 'abcd', oauth_token_secret: '1234'\n removeMissingValuesFrom?: object; // Should missing values be sent? (empty strings, `null`, and `undefined` only — `[]`, `{}`, and `false` will still be sent\n serializeValueForCurlies?: /FunctionSchema; // A function to customize how to serialize a value for curlies `{{var}}` in the request object. By default, when this is u\n skipThrowForStatus?: boolean; // If `true`, don't throw an exception for response 400 <= status < 600 automatically before resolving with the response. D\n skipEncodingChars?: string; // Contains the characters that you want left unencoded in the query params (`req.params`). If unspecified, `z.request()` w\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/RequestSchema\",\n \"description\": \"A representation of a HTTP request - you can use the `{{syntax}}` to inject authentication, field or global variables.\",\n \"type\": \"object\",\n \"properties\": {\n \"method\": {\n \"description\": \"The HTTP method for the request.\",\n \"type\": \"string\",\n \"default\": \"GET\",\n \"enum\": [\n \"GET\",\n \"PUT\",\n \"POST\",\n \"PATCH\",\n \"DELETE\",\n \"HEAD\"\n ]\n },\n \"url\": {\n \"description\": \"A URL for the request (we will parse the querystring and merge with params). Keys and values will not be re-encoded.\",\n \"type\": \"string\"\n },\n \"body\": {\n \"description\": \"Can be nothing, a raw string or JSON (object or array).\",\n \"oneOf\": [\n {\n \"type\": \"null\"\n },\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"object\"\n },\n {\n \"type\": \"array\"\n }\n ]\n },\n \"params\": {\n \"description\": \"A mapping of the querystring - will get merged with any query params in the URL. Keys and values will be encoded.\",\n \"$ref\": \"/FlatObjectSchema\"\n },\n \"headers\": {\n \"description\": \"The HTTP headers for the request.\",\n \"$ref\": \"/FlatObjectSchema\"\n },\n \"auth\": {\n \"description\": \"An object holding the auth parameters for OAuth1 request signing, like `{oauth_token: 'abcd', oauth_token_secret: '1234'}`. Or an array reserved (i.e. not implemented yet) to hold the username and password for Basic Auth. Like `['AzureDiamond', 'hunter2']`.\",\n \"oneOf\": [\n {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\",\n \"minProperties\": 2,\n \"maxProperties\": 2\n }\n },\n {\n \"$ref\": \"/FlatObjectSchema\"\n }\n ]\n },\n \"removeMissingValuesFrom\": {\n \"description\": \"Should missing values be sent? (empty strings, `null`, and `undefined` only \\u2014 `[]`, `{}`, and `false` will still be sent). Allowed fields are `params` and `body`. The default is `false`, ex: ```removeMissingValuesFrom: { params: false, body: false }```\",\n \"type\": \"object\",\n \"properties\": {\n \"params\": {\n \"description\": \"Refers to data sent via a requests query params (`req.params`)\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"body\": {\n \"description\": \"Refers to tokens sent via a requsts body (`req.body`)\",\n \"type\": \"boolean\",\n \"default\": false\n }\n },\n \"additionalProperties\": false\n },\n \"serializeValueForCurlies\": {\n \"description\": \"A function to customize how to serialize a value for curlies `{{var}}` in the request object. By default, when this is unspecified, the request client only replaces curlies where variables are strings, and would throw an error for non-strings. The function should accepts a single argument as the value to be serialized and return the string representation of the argument.\",\n \"$ref\": \"/FunctionSchema\"\n },\n \"skipThrowForStatus\": {\n \"description\": \"If `true`, don't throw an exception for response 400 <= status < 600 automatically before resolving with the response. Defaults to `false`.\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"skipEncodingChars\": {\n \"description\": \"Contains the characters that you want left unencoded in the query params (`req.params`). If unspecified, `z.request()` will percent-encode non-ascii characters and these reserved characters: ``:$/?#[]@$&+,;=^@`\\\\``.\",\n \"type\": \"string\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "RequestSchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/RequestSchema", "required": [], "properties": ["method", "url", "body", "params", "headers", "auth", "removeMissingValuesFrom", "serializeValueForCurlies", "skipThrowForStatus", "skipEncodingChars"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:redirectrequestschema", "kind": "schema_type", "key": "RedirectRequestSchema", "title": "RedirectRequestSchema", "summary": "A representation of a HTTP redirect - you can use the `{{syntax}}` to inject authentication, field or global variables.", "body": "# `RedirectRequestSchema`\n\n> A representation of a HTTP redirect - you can use the `{{syntax}}` to inject authentication, field or global variables.\n\n## High-level description\n\nA representation of a HTTP redirect - you can use the `{{syntax}}` to inject authentication, field or global variables.\n\n## Internals\n\nJSON Schema id `/RedirectRequestSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n method?: string; // The HTTP method for the request.\n url?: string; // A URL for the request (we will parse the querystring and merge with params). Keys and values will not be re-encoded.\n params?: /FlatObjectSchema; // A mapping of the querystring - will get merged with any query params in the URL. Keys and values will be encoded.\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/RedirectRequestSchema\",\n \"description\": \"A representation of a HTTP redirect - you can use the `{{syntax}}` to inject authentication, field or global variables.\",\n \"type\": \"object\",\n \"properties\": {\n \"method\": {\n \"description\": \"The HTTP method for the request.\",\n \"type\": \"string\",\n \"default\": \"GET\",\n \"enum\": [\n \"GET\"\n ]\n },\n \"url\": {\n \"description\": \"A URL for the request (we will parse the querystring and merge with params). Keys and values will not be re-encoded.\",\n \"type\": \"string\"\n },\n \"params\": {\n \"description\": \"A mapping of the querystring - will get merged with any query params in the URL. Keys and values will be encoded.\",\n \"$ref\": \"/FlatObjectSchema\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "RedirectRequestSchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/RedirectRequestSchema", "required": [], "properties": ["method", "url", "params"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:authfieldsschema", "kind": "schema_type", "key": "AuthFieldsSchema", "title": "AuthFieldsSchema", "summary": "An array or collection of authentication fields.", "body": "# `AuthFieldsSchema`\n\n> An array or collection of authentication fields.\n\n## High-level description\n\nAn array or collection of authentication fields.\n\n## Internals\n\nJSON Schema id `/AuthFieldsSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/AuthFieldsSchema\",\n \"description\": \"An array or collection of authentication fields.\",\n \"type\": \"array\",\n \"items\": {\n \"oneOf\": [\n {\n \"$ref\": \"/AuthFieldSchema\"\n }\n ]\n }\n}\n```", "usage": "", "signature": "AuthFieldsSchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/AuthFieldsSchema", "required": [], "properties": [], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:authenticationbasicconfigschema", "kind": "schema_type", "key": "AuthenticationBasicConfigSchema", "title": "AuthenticationBasicConfigSchema", "summary": "Config for Basic Authentication. No extra properties are required to setup Basic Auth, so you can leave this empty if your app uses Basic Auth.", "body": "# `AuthenticationBasicConfigSchema`\n\n> Config for Basic Authentication. No extra properties are required to setup Basic Auth, so you can leave this empty if your app uses Basic Auth.\n\n## High-level description\n\nConfig for Basic Authentication. No extra properties are required to setup Basic Auth, so you can leave this empty if your app uses Basic Auth.\n\n## Internals\n\nJSON Schema id `/AuthenticationBasicConfigSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/AuthenticationBasicConfigSchema\",\n \"description\": \"Config for Basic Authentication. No extra properties are required to setup Basic Auth, so you can leave this empty if your app uses Basic Auth.\",\n \"type\": \"object\",\n \"properties\": {},\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "AuthenticationBasicConfigSchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/AuthenticationBasicConfigSchema", "required": [], "properties": [], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:authenticationcustomconfigschema", "kind": "schema_type", "key": "AuthenticationCustomConfigSchema", "title": "AuthenticationCustomConfigSchema", "summary": "Config for custom authentication (like API keys). No extra properties are required to setup this auth type, so you can leave this empty if your app uses a custom auth method.", "body": "# `AuthenticationCustomConfigSchema`\n\n> Config for custom authentication (like API keys). No extra properties are required to setup this auth type, so you can leave this empty if your app uses a custom auth method.\n\n## High-level description\n\nConfig for custom authentication (like API keys). No extra properties are required to setup this auth type, so you can leave this empty if your app uses a custom auth method.\n\n## Internals\n\nJSON Schema id `/AuthenticationCustomConfigSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n sendCode?: any; // EXPERIMENTAL: Define the call Zapier should make to send the OTP code.\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/AuthenticationCustomConfigSchema\",\n \"description\": \"Config for custom authentication (like API keys). No extra properties are required to setup this auth type, so you can leave this empty if your app uses a custom auth method.\",\n \"type\": \"object\",\n \"properties\": {\n \"sendCode\": {\n \"description\": \"EXPERIMENTAL: Define the call Zapier should make to send the OTP code.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "AuthenticationCustomConfigSchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/AuthenticationCustomConfigSchema", "required": [], "properties": ["sendCode"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:authenticationdigestconfigschema", "kind": "schema_type", "key": "AuthenticationDigestConfigSchema", "title": "AuthenticationDigestConfigSchema", "summary": "Config for Digest Authentication. No extra properties are required to setup Digest Auth, so you can leave this empty if your app uses Digets Auth.", "body": "# `AuthenticationDigestConfigSchema`\n\n> Config for Digest Authentication. No extra properties are required to setup Digest Auth, so you can leave this empty if your app uses Digets Auth.\n\n## High-level description\n\nConfig for Digest Authentication. No extra properties are required to setup Digest Auth, so you can leave this empty if your app uses Digets Auth.\n\n## Internals\n\nJSON Schema id `/AuthenticationDigestConfigSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/AuthenticationDigestConfigSchema\",\n \"description\": \"Config for Digest Authentication. No extra properties are required to setup Digest Auth, so you can leave this empty if your app uses Digets Auth.\",\n \"type\": \"object\",\n \"properties\": {},\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "AuthenticationDigestConfigSchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/AuthenticationDigestConfigSchema", "required": [], "properties": [], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:authenticationoauth1configschema", "kind": "schema_type", "key": "AuthenticationOAuth1ConfigSchema", "title": "AuthenticationOAuth1ConfigSchema", "summary": "Config for OAuth1 authentication.", "body": "# `AuthenticationOAuth1ConfigSchema`\n\n> Config for OAuth1 authentication.\n\n## High-level description\n\nConfig for OAuth1 authentication.\n\n## Internals\n\nJSON Schema id `/AuthenticationOAuth1ConfigSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: getRequestToken, authorizeUrl, getAccessToken\n getRequestToken: any; // Define where Zapier will acquire a request token which is used for the rest of the three legged authentication process.\n authorizeUrl: any; // Define where Zapier will redirect the user to authorize our app. Typically, you should append an `oauth_token` querystri\n getAccessToken: any; // Define how Zapier fetches an access token from the API\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/AuthenticationOAuth1ConfigSchema\",\n \"description\": \"Config for OAuth1 authentication.\",\n \"type\": \"object\",\n \"required\": [\n \"getRequestToken\",\n \"authorizeUrl\",\n \"getAccessToken\"\n ],\n \"properties\": {\n \"getRequestToken\": {\n \"description\": \"Define where Zapier will acquire a request token which is used for the rest of the three legged authentication process.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"authorizeUrl\": {\n \"description\": \"Define where Zapier will redirect the user to authorize our app. Typically, you should append an `oauth_token` querystring parameter to the request.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RedirectRequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"getAccessToken\": {\n \"description\": \"Define how Zapier fetches an access token from the API\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "AuthenticationOAuth1ConfigSchema required=[getRequestToken, authorizeUrl, getAccessToken]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/AuthenticationOAuth1ConfigSchema", "required": ["getRequestToken", "authorizeUrl", "getAccessToken"], "properties": ["getRequestToken", "authorizeUrl", "getAccessToken"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:authenticationoauth2configschema", "kind": "schema_type", "key": "AuthenticationOAuth2ConfigSchema", "title": "AuthenticationOAuth2ConfigSchema", "summary": "Config for OAuth2 authentication.", "body": "# `AuthenticationOAuth2ConfigSchema`\n\n> Config for OAuth2 authentication.\n\n## High-level description\n\nConfig for OAuth2 authentication.\n\n## Internals\n\nJSON Schema id `/AuthenticationOAuth2ConfigSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: authorizeUrl, getAccessToken\n authorizeUrl: any; // Define where Zapier will redirect the user to authorize our app. Note: we append the redirect URL and state parameters t\n getAccessToken: any; // Define how Zapier fetches an access token from the API\n refreshAccessToken?: any; // Define how Zapier will refresh the access token from the API\n codeParam?: string; // Define a non-standard code param Zapier should scrape instead.\n scope?: string; // What scope should Zapier request?\n autoRefresh?: boolean; // Should Zapier invoke `refreshAccessToken` when we receive an error for a 401 response?\n enablePkce?: boolean; // Should Zapier use PKCE for OAuth2?\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/AuthenticationOAuth2ConfigSchema\",\n \"description\": \"Config for OAuth2 authentication.\",\n \"type\": \"object\",\n \"required\": [\n \"authorizeUrl\",\n \"getAccessToken\"\n ],\n \"properties\": {\n \"authorizeUrl\": {\n \"description\": \"Define where Zapier will redirect the user to authorize our app. Note: we append the redirect URL and state parameters to return value of this function.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RedirectRequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"getAccessToken\": {\n \"description\": \"Define how Zapier fetches an access token from the API\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"refreshAccessToken\": {\n \"description\": \"Define how Zapier will refresh the access token from the API\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"codeParam\": {\n \"description\": \"Define a non-standard code param Zapier should scrape instead.\",\n \"type\": \"string\"\n },\n \"scope\": {\n \"description\": \"What scope should Zapier request?\",\n \"type\": \"string\"\n },\n \"autoRefresh\": {\n \"description\": \"Should Zapier invoke `refreshAccessToken` when we receive an error for a 401 response?\",\n \"type\": \"boolean\"\n },\n \"enablePkce\": {\n \"description\": \"Should Zapier use PKCE for OAuth2?\",\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "AuthenticationOAuth2ConfigSchema required=[authorizeUrl, getAccessToken]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/AuthenticationOAuth2ConfigSchema", "required": ["authorizeUrl", "getAccessToken"], "properties": ["authorizeUrl", "getAccessToken", "refreshAccessToken", "codeParam", "scope", "autoRefresh", "enablePkce"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:authenticationsessionconfigschema", "kind": "schema_type", "key": "AuthenticationSessionConfigSchema", "title": "AuthenticationSessionConfigSchema", "summary": "Config for session authentication.", "body": "# `AuthenticationSessionConfigSchema`\n\n> Config for session authentication.\n\n## High-level description\n\nConfig for session authentication.\n\n## Internals\n\nJSON Schema id `/AuthenticationSessionConfigSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: perform\n perform: any; // Define how Zapier fetches the additional authData needed to make API calls.\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/AuthenticationSessionConfigSchema\",\n \"description\": \"Config for session authentication.\",\n \"type\": \"object\",\n \"required\": [\n \"perform\"\n ],\n \"properties\": {\n \"perform\": {\n \"description\": \"Define how Zapier fetches the additional authData needed to make API calls.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "AuthenticationSessionConfigSchema required=[perform]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/AuthenticationSessionConfigSchema", "required": ["perform"], "properties": ["perform"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:refresourceschema", "kind": "schema_type", "key": "RefResourceSchema", "title": "RefResourceSchema", "summary": "Reference a resource by key and the data it returns. In the format of: `{resource_key}.{foreign_key}(.{human_label_key})`.", "body": "# `RefResourceSchema`\n\n> Reference a resource by key and the data it returns. In the format of: `{resource_key}.{foreign_key}(.{human_label_key})`.\n\n## High-level description\n\nReference a resource by key and the data it returns. In the format of: `{resource_key}.{foreign_key}(.{human_label_key})`.\n\n## Internals\n\nJSON Schema id `/RefResourceSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/RefResourceSchema\",\n \"description\": \"Reference a resource by key and the data it returns. In the format of: `{resource_key}.{foreign_key}(.{human_label_key})`.\",\n \"type\": \"string\",\n \"pattern\": \"^[a-zA-Z0-9_]+\\\\.[a-zA-Z0-9_\\\\s\\\\[\\\\]]+(\\\\.[a-zA-Z0-9_\\\\s\\\\[\\\\]]+(,[a-zA-Z0-9_\\\\s\\\\[\\\\]]+)*)?$\"\n}\n```", "usage": "", "signature": "RefResourceSchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/RefResourceSchema", "required": [], "properties": [], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:fielddynamicchoicesschema", "kind": "schema_type", "key": "FieldDynamicChoicesSchema", "title": "FieldDynamicChoicesSchema", "summary": "Describes dynamic dropdowns powered by a perform function or request.", "body": "# `FieldDynamicChoicesSchema`\n\n> Describes dynamic dropdowns powered by a perform function or request.\n\n## High-level description\n\nDescribes dynamic dropdowns powered by a perform function or request.\n\n## Internals\n\nJSON Schema id `/FieldDynamicChoicesSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: perform\n perform: any; // A function or request that returns choices for this dynamic dropdown.\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/FieldDynamicChoicesSchema\",\n \"description\": \"Describes dynamic dropdowns powered by a perform function or request.\",\n \"type\": \"object\",\n \"required\": [\n \"perform\"\n ],\n \"properties\": {\n \"perform\": {\n \"description\": \"A function or request that returns choices for this dynamic dropdown.\",\n \"oneOf\": [\n {\n \"$ref\": \"/FunctionSchema\"\n },\n {\n \"$ref\": \"/RequestSchema\"\n }\n ]\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "FieldDynamicChoicesSchema required=[perform]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/FieldDynamicChoicesSchema", "required": ["perform"], "properties": ["perform"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:fieldmetaschema", "kind": "schema_type", "key": "FieldMetaSchema", "title": "FieldMetaSchema", "summary": "Allows for additional metadata to be stored on the field.", "body": "# `FieldMetaSchema`\n\n> Allows for additional metadata to be stored on the field.\n\n## High-level description\n\nAllows for additional metadata to be stored on the field.\n\n## Internals\n\nJSON Schema id `/FieldMetaSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/FieldMetaSchema\",\n \"type\": \"object\",\n \"description\": \"Allows for additional metadata to be stored on the field.\",\n \"patternProperties\": {\n \"[^\\\\s]+\": {\n \"description\": \"Only string, integer or boolean values are allowed.\",\n \"anyOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"integer\"\n },\n {\n \"type\": \"boolean\"\n }\n ]\n }\n }\n}\n```", "usage": "", "signature": "FieldMetaSchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/FieldMetaSchema", "required": [], "properties": [], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:keyschema", "kind": "schema_type", "key": "KeySchema", "title": "KeySchema", "summary": "A unique identifier for this item.", "body": "# `KeySchema`\n\n> A unique identifier for this item.\n\n## High-level description\n\nA unique identifier for this item.\n\n## Internals\n\nJSON Schema id `/KeySchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/KeySchema\",\n \"description\": \"A unique identifier for this item.\",\n \"type\": \"string\",\n \"minLength\": 2,\n \"pattern\": \"^[a-zA-Z]+[a-zA-Z0-9_]*$\"\n}\n```", "usage": "", "signature": "KeySchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/KeySchema", "required": [], "properties": [], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:jsonschemaschema", "kind": "schema_type", "key": "JsonSchemaSchema", "title": "JsonSchemaSchema", "summary": "A JSON Schema object that describes the expected structure of a JSON value. Validated against JSON Schema Draft 4, 6, or 7 meta-schema (based on the `$schema` field, defaulting to Draft 7) via the validateJsonFieldSchema functional constraint.", "body": "# `JsonSchemaSchema`\n\n> A JSON Schema object that describes the expected structure of a JSON value. Validated against JSON Schema Draft 4, 6, or 7 meta-schema (based on the `$schema` field, defaulting to Draft 7) via the validateJsonFieldSchema functional constraint.\n\n## High-level description\n\nA JSON Schema object that describes the expected structure of a JSON value. Validated against JSON Schema Draft 4, 6, or 7 meta-schema (based on the `$schema` field, defaulting to Draft 7) via the validateJsonFieldSchema functional constraint.\n\n## Internals\n\nJSON Schema id `/JsonSchemaSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/JsonSchemaSchema\",\n \"description\": \"A JSON Schema object that describes the expected structure of a JSON value. Validated against JSON Schema Draft 4, 6, or 7 meta-schema (based on the `$schema` field, defaulting to Draft 7) via the validateJsonFieldSchema functional constraint.\",\n \"type\": \"object\",\n \"additionalProperties\": true\n}\n```", "usage": "", "signature": "JsonSchemaSchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/JsonSchemaSchema", "required": [], "properties": [], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:plaininputfieldschema", "kind": "schema_type", "key": "PlainInputFieldSchema", "title": "PlainInputFieldSchema", "summary": "Field schema specialized for input fields. In addition to the requirements below, the following keys are mutually exclusive:\n\n* `children` & `list`\n* `children` & `dict`\n* `children` & `type`\n* `children` & `placeholder`\n* `children` & `helpText`\n* `children` & `default`\n* `dict` & `list`\n* `dynamic` & `dict`\n* `dynamic` & `choices`", "body": "# `PlainInputFieldSchema`\n\n> Field schema specialized for input fields. In addition to the requirements below, the following keys are mutually exclusive:\n\n* `children` & `list`\n* `children` & `dict`\n* `children` & `type`\n* `children` & `placeholder`\n* `children` & `helpText`\n* `children` & `default`\n* `dict` & `list`\n* `dynamic` & `dict`\n* `dynamic` & `choices`\n\n## High-level description\n\nField schema specialized for input fields. In addition to the requirements below, the following keys are mutually exclusive:\n\n* `children` & `list`\n* `children` & `dict`\n* `children` & `type`\n* `children` & `placeholder`\n* `children` & `helpText`\n* `children` & `default`\n* `dict` & `list`\n* `dynamic` & `dict`\n* `dynamic` & `choices`\n\n## Internals\n\nJSON Schema id `/PlainInputFieldSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: key\n key: string; // A unique machine readable key for this value (IE: \"fname\").\n label?: string; // A human readable label for this value (IE: \"First Name\").\n type?: string; // The type of this value. Use `string` for basic text input, `text` for a large, `<textarea>` style box, and `code` for a \n required?: boolean; // If this value is required or not.\n default?: string; // A default value that is saved the first time a Zap is created.\n list?: boolean; // Acts differently when used in inputFields vs. when used in outputFields. In inputFields: Can a user provide multiples of\n children?: array; // An array of child fields that define the structure of a sub-object for this field. Usually used for line items.\n dict?: boolean; // Is this field a key/value input?\n helpText?: string; // A human readable description of this value (IE: \"The first part of a full name.\"). You can use Markdown.\n search?: /RefResourceSchema; // A reference to a search that will guide the user to add a search step to populate this field when creating a Zap.\n dynamic?: /RefResourceSchema; // A reference to a trigger that will power a dynamic dropdown.\n dependsOn?: array; // Specifies which other input fields this field depends on. These must be filled before this one becomes enabled, and when\n resource?: string; // Explicitly links this input field to a resource. Use the resource key (e.g., \"spreadsheet\") or dot notation for resource\n choices?: any; // Describes how to populate this dropdown. Can be a static list or a dynamic object with pagination and search support.\n placeholder?: string; // An example value that is not saved.\n altersDynamicFields?: boolean; // Does the value of this field affect the definitions of other fields in the set?\n computed?: boolean; // Is this field automatically populated (and hidden from the user)? Note: Only OAuth, Session Auth, and certain internal u\n inputFormat?: string; // Useful when you expect the input to be part of a longer string. Put \"{{input}}\" in place of the user's input (IE: \"https\n meta?: /FieldMetaSchema; // Allows for additional metadata to be stored on the field. Supports simple key-values only (no sub-objects or arrays).\n group?: /KeySchema; // References a group key from the operation's inputFieldGroups to organize this field with others.\n schema?: /JsonSchemaSchema; // A JSON Schema object that describes the expected structure of the JSON value. Only valid when `type` is `json`.\n```\n\n## Schema\n\n```json\n{\n \"description\": \"Field schema specialized for input fields. In addition to the requirements below, the following keys are mutually exclusive:\\n\\n* `children` & `list`\\n* `children` & `dict`\\n* `children` & `type`\\n* `children` & `placeholder`\\n* `children` & `helpText`\\n* `children` & `default`\\n* `dict` & `list`\\n* `dynamic` & `dict`\\n* `dynamic` & `choices`\",\n \"id\": \"/PlainInputFieldSchema\",\n \"type\": \"object\",\n \"required\": [\n \"key\"\n ],\n \"properties\": {\n \"key\": {\n \"description\": \"A unique machine readable key for this value (IE: \\\"fname\\\").\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"label\": {\n \"description\": \"A human readable label for this value (IE: \\\"First Name\\\").\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"type\": {\n \"description\": \"The type of this value. Use `string` for basic text input, `text` for a large, `<textarea>` style box, and `code` for a `<textarea>` with a fixed-width font. Field type of `file` will accept either a file object or a string. If a URL is provided in the string, Zapier will automatically make a GET for that file. Otherwise, a .txt file will be generated.\",\n \"type\": \"string\",\n \"enum\": [\n \"string\",\n \"text\",\n \"integer\",\n \"number\",\n \"boolean\",\n \"datetime\",\n \"file\",\n \"password\",\n \"copy\",\n \"code\",\n \"json\"\n ]\n },\n \"required\": {\n \"description\": \"If this value is required or not.\",\n \"type\": \"boolean\"\n },\n \"default\": {\n \"description\": \"A default value that is saved the first time a Zap is created.\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"list\": {\n \"description\": \"Acts differently when used in inputFields vs. when used in outputFields. In inputFields: Can a user provide multiples of this field? In outputFields: Does this field return an array of items of type `type`?\",\n \"type\": \"boolean\"\n },\n \"children\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"/PlainInputFieldSchema\"\n },\n \"description\": \"An array of child fields that define the structure of a sub-object for this field. Usually used for line items.\",\n \"minItems\": 1\n },\n \"dict\": {\n \"description\": \"Is this field a key/value input?\",\n \"type\": \"boolean\"\n },\n \"helpText\": {\n \"description\": \"A human readable description of this value (IE: \\\"The first part of a full name.\\\"). You can use Markdown.\",\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 1000\n },\n \"search\": {\n \"description\": \"A reference to a search that will guide the user to add a search step to populate this field when creating a Zap.\",\n \"$ref\": \"/RefResourceSchema\"\n },\n \"dynamic\": {\n \"description\": \"A reference to a trigger that will power a dynamic dropdown.\",\n \"$ref\": \"/RefResourceSchema\"\n },\n \"dependsOn\": {\n \"description\": \"Specifies which other input fields this field depends on. These must be filled before this one becomes enabled, and when their values change, this field's value should be cleared.\",\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"resource\": {\n \"description\": \"Explicitly links this input field to a resource. Use the resource key (e.g., \\\"spreadsheet\\\") or dot notation for resource fields (e.g., \\\"spreadsheet.url\\\"). If not set for dynamic dropdowns, the resource is derived implicitly from the `dynamic` property.\",\n \"type\": \"string\",\n \"minLength\": 1,\n \"pattern\": \"^[a-zA-Z0-9_]+(\\\\.[a-zA-Z0-9_]+)?$\"\n },\n \"choices\": {\n \"description\": \"Describes how to populate this dropdown. Can be a static list or a dynamic object with pagination and search support.\",\n \"oneOf\": [\n {\n \"$ref\": \"/FieldChoicesSchema\"\n },\n {\n \"$ref\": \"/FieldDynamicChoicesSchema\"\n }\n ]\n },\n \"placeholder\": {\n \"description\": \"An example value that is not saved.\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"altersDynamicFields\": {\n \"description\": \"Does the value of this field affect the definitions of other fields in the set?\",\n \"type\": \"boolean\"\n },\n \"computed\": {\n \"description\": \"Is this field automatically populated (and hidden from the user)? Note: Only OAuth, Session Auth, and certain internal use cases support fields with this key.\",\n \"type\": \"boolean\"\n },\n \"inputFormat\": {\n \"description\": \"Useful when you expect the input to be part of a longer string. Put \\\"{{input}}\\\" in place of the user's input (IE: \\\"https://{{input}}.yourdomain.com\\\").\",\n \"type\": \"string\",\n \"pattern\": \"^.*{{input}}.*$\"\n },\n \"meta\": {\n \"description\": \"Allows for additional metadata to be stored on the field. Supports simple key-values only (no sub-objects or arrays).\",\n \"$ref\": \"/FieldMetaSchema\"\n },\n \"group\": {\n \"description\": \"References a group key from the operation's inputFieldGroups to organize this field with others.\",\n \"$ref\": \"/KeySchema\"\n },\n \"schema\": {\n \"description\": \"A JSON Schema object that describes the expected structure of the JSON value. Only valid when `type` is `json`.\",\n \"$ref\": \"/JsonSchemaSchema\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "PlainInputFieldSchema required=[key]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/PlainInputFieldSchema", "required": ["key"], "properties": ["key", "label", "type", "required", "default", "list", "children", "dict", "helpText", "search", "dynamic", "dependsOn", "resource", "choices", "placeholder", "altersDynamicFields", "computed", "inputFormat", "meta", "group", "schema"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:inputfieldgroupschema", "kind": "schema_type", "key": "InputFieldGroupSchema", "title": "InputFieldGroupSchema", "summary": "Object for visual grouping of input fields.", "body": "# `InputFieldGroupSchema`\n\n> Object for visual grouping of input fields.\n\n## High-level description\n\nObject for visual grouping of input fields.\n\n## Internals\n\nJSON Schema id `/InputFieldGroupSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: key\n key: /KeySchema; // The unique identifier for this group.\n label?: string; // The human-readable name for the group.\n emphasize?: boolean; // Whether this group should be visually emphasized in the UI.\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/InputFieldGroupSchema\",\n \"description\": \"Object for visual grouping of input fields.\",\n \"type\": \"object\",\n \"required\": [\n \"key\"\n ],\n \"properties\": {\n \"key\": {\n \"description\": \"The unique identifier for this group.\",\n \"$ref\": \"/KeySchema\"\n },\n \"label\": {\n \"description\": \"The human-readable name for the group.\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"emphasize\": {\n \"description\": \"Whether this group should be visually emphasized in the UI.\",\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "InputFieldGroupSchema required=[key]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/InputFieldGroupSchema", "required": ["key"], "properties": ["key", "label", "emphasize"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:plainoutputfieldschema", "kind": "schema_type", "key": "PlainOutputFieldSchema", "title": "PlainOutputFieldSchema", "summary": "Field schema specialized for output fields. In addition to the requirements below, the following keys are mutually exclusive:\n\n* `children` & `list`\n* `children` & `dict`\n* `children` & `type`\n* `children` & `placeholder`\n* `children` & `helpText`\n* `children` & `default`\n* `dict` & `list`\n* `dynamic` & `dict`\n* `dynamic` & `choices`", "body": "# `PlainOutputFieldSchema`\n\n> Field schema specialized for output fields. In addition to the requirements below, the following keys are mutually exclusive:\n\n* `children` & `list`\n* `children` & `dict`\n* `children` & `type`\n* `children` & `placeholder`\n* `children` & `helpText`\n* `children` & `default`\n* `dict` & `list`\n* `dynamic` & `dict`\n* `dynamic` & `choices`\n\n## High-level description\n\nField schema specialized for output fields. In addition to the requirements below, the following keys are mutually exclusive:\n\n* `children` & `list`\n* `children` & `dict`\n* `children` & `type`\n* `children` & `placeholder`\n* `children` & `helpText`\n* `children` & `default`\n* `dict` & `list`\n* `dynamic` & `dict`\n* `dynamic` & `choices`\n\n## Internals\n\nJSON Schema id `/PlainOutputFieldSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: key\n key: string; // A unique machine readable key for this value (IE: \"fname\").\n label?: string; // A human readable label for this value (IE: \"First Name\").\n type?: string; // The type of this value. Field type of `file` will accept either a file object or a string. If a URL is provided in the s\n required?: boolean; // If this value is required or not.\n default?: string; // A default value that is saved the first time a Zap is created.\n list?: boolean; // Acts differently when used in inputFields vs. when used in outputFields. In inputFields: Can a user provide multiples of\n children?: array; // An array of child fields that define the structure of a sub-object for this field. Usually used for line items.\n dict?: boolean; // Is this field a key/value input?\n primary?: boolean; // Use this field as part of the primary key for deduplication. You can set multiple fields as \"primary\", provided they are\n steadyState?: boolean; // Prevents triggering on new output until all values for fields with this property remain unchanged for 2 polls. It can be\n sample?: any; // An example value for this field. Can be any type (string, number, boolean, object, array, null) to match the expected fi\n```\n\n## Schema\n\n```json\n{\n \"description\": \"Field schema specialized for output fields. In addition to the requirements below, the following keys are mutually exclusive:\\n\\n* `children` & `list`\\n* `children` & `dict`\\n* `children` & `type`\\n* `children` & `placeholder`\\n* `children` & `helpText`\\n* `children` & `default`\\n* `dict` & `list`\\n* `dynamic` & `dict`\\n* `dynamic` & `choices`\",\n \"id\": \"/PlainOutputFieldSchema\",\n \"type\": \"object\",\n \"required\": [\n \"key\"\n ],\n \"properties\": {\n \"key\": {\n \"description\": \"A unique machine readable key for this value (IE: \\\"fname\\\").\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"label\": {\n \"description\": \"A human readable label for this value (IE: \\\"First Name\\\").\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"type\": {\n \"description\": \"The type of this value. Field type of `file` will accept either a file object or a string. If a URL is provided in the string, Zapier will automatically make a GET for that file. Otherwise, a .txt file will be generated.\",\n \"type\": \"string\",\n \"enum\": [\n \"string\",\n \"number\",\n \"boolean\",\n \"datetime\",\n \"file\",\n \"password\",\n \"integer\"\n ]\n },\n \"required\": {\n \"description\": \"If this value is required or not.\",\n \"type\": \"boolean\"\n },\n \"default\": {\n \"description\": \"A default value that is saved the first time a Zap is created.\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"list\": {\n \"description\": \"Acts differently when used in inputFields vs. when used in outputFields. In inputFields: Can a user provide multiples of this field? In outputFields: Does this field return an array of items of type `type`?\",\n \"type\": \"boolean\"\n },\n \"children\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"/PlainOutputFieldSchema\"\n },\n \"description\": \"An array of child fields that define the structure of a sub-object for this field. Usually used for line items.\",\n \"minItems\": 1\n },\n \"dict\": {\n \"description\": \"Is this field a key/value input?\",\n \"type\": \"boolean\"\n },\n \"primary\": {\n \"description\": \"Use this field as part of the primary key for deduplication. You can set multiple fields as \\\"primary\\\", provided they are unique together. If no fields are set, Zapier will default to using the `id` field. `primary` only makes sense for `outputFields`. It only works in static `outputFields`; will not work in custom/dynamic `outputFields`. For more information, see [How deduplication works in Zapier](https://platform.zapier.com/build/deduplication).\",\n \"type\": \"boolean\"\n },\n \"steadyState\": {\n \"description\": \"Prevents triggering on new output until all values for fields with this property remain unchanged for 2 polls. It can be used to, e.g., not trigger on a new contact until the contact has completed typing their name. NOTE that this only applies to the `outputFields` of polling triggers.\",\n \"type\": \"boolean\"\n },\n \"sample\": {\n \"description\": \"An example value for this field. Can be any type (string, number, boolean, object, array, null) to match the expected field output. Values provided here will be combined with values in the operation level `sample` field, with this field taking precedence. This is most useful when using a function to generate dynamic `outputFields`.\",\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"number\"\n },\n {\n \"type\": \"boolean\"\n },\n {\n \"type\": \"object\"\n },\n {\n \"type\": \"array\"\n },\n {\n \"type\": \"null\"\n }\n ]\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "PlainOutputFieldSchema required=[key]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/PlainOutputFieldSchema", "required": ["key"], "properties": ["key", "label", "type", "required", "default", "list", "children", "dict", "primary", "steadyState", "sample"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:throttleoverrideobjectschema", "kind": "schema_type", "key": "ThrottleOverrideObjectSchema", "title": "ThrottleOverrideObjectSchema", "summary": "EXPERIMENTAL: Overrides the original throttle configuration based on a Zapier account attribute.", "body": "# `ThrottleOverrideObjectSchema`\n\n> EXPERIMENTAL: Overrides the original throttle configuration based on a Zapier account attribute.\n\n## High-level description\n\nEXPERIMENTAL: Overrides the original throttle configuration based on a Zapier account attribute.\n\n## Internals\n\nJSON Schema id `/ThrottleOverrideObjectSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: window, limit, filter\n window: integer; // The timeframe, in seconds, within which the system tracks the number of invocations for an action. The number of invocat\n limit: integer; // The maximum number of invocations for an action, allowed within the timeframe window.\n filter: string; // Account-based attribute to override the throttle by. You can set to one of the following: \"free\", \"trial\", \"paid\". There\n retry?: boolean; // The effect of throttling on the tasks of the action. `true` means throttled tasks are automatically retried after some d\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/ThrottleOverrideObjectSchema\",\n \"description\": \"EXPERIMENTAL: Overrides the original throttle configuration based on a Zapier account attribute.\",\n \"type\": \"object\",\n \"required\": [\n \"window\",\n \"limit\",\n \"filter\"\n ],\n \"properties\": {\n \"window\": {\n \"description\": \"The timeframe, in seconds, within which the system tracks the number of invocations for an action. The number of invocations begins at zero at the start of each window.\",\n \"type\": \"integer\"\n },\n \"limit\": {\n \"description\": \"The maximum number of invocations for an action, allowed within the timeframe window.\",\n \"type\": \"integer\"\n },\n \"filter\": {\n \"description\": \"Account-based attribute to override the throttle by. You can set to one of the following: \\\"free\\\", \\\"trial\\\", \\\"paid\\\". Therefore, the throttle scope would be automatically set to \\\"account\\\" and ONLY the accounts based on the specified filter will have their requests throttled based on the throttle overrides while the rest are throttled based on the original configuration.\",\n \"type\": \"string\",\n \"enum\": [\n \"free\",\n \"trial\",\n \"paid\"\n ]\n },\n \"retry\": {\n \"description\": \"The effect of throttling on the tasks of the action. `true` means throttled tasks are automatically retried after some delay, while `false` means tasks are held without retry. It defaults to `true`. NOTE that it has no effect on polling triggers and should not be set.\",\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "ThrottleOverrideObjectSchema required=[window, limit, filter]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/ThrottleOverrideObjectSchema", "required": ["window", "limit", "filter"], "properties": ["window", "limit", "filter", "retry"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:inputfieldsschema", "kind": "schema_type", "key": "InputFieldsSchema", "title": "InputFieldsSchema", "summary": "An array or collection of input fields.", "body": "# `InputFieldsSchema`\n\n> An array or collection of input fields.\n\n## High-level description\n\nAn array or collection of input fields.\n\n## Internals\n\nJSON Schema id `/InputFieldsSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/InputFieldsSchema\",\n \"description\": \"An array or collection of input fields.\",\n \"type\": \"array\",\n \"items\": {\n \"oneOf\": [\n {\n \"$ref\": \"/PlainInputFieldSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n }\n}\n```", "usage": "", "signature": "InputFieldsSchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/InputFieldsSchema", "required": [], "properties": [], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:inputfieldgroupsschema", "kind": "schema_type", "key": "InputFieldGroupsSchema", "title": "InputFieldGroupsSchema", "summary": "An array or collection of input field groups.", "body": "# `InputFieldGroupsSchema`\n\n> An array or collection of input field groups.\n\n## High-level description\n\nAn array or collection of input field groups.\n\n## Internals\n\nJSON Schema id `/InputFieldGroupsSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/InputFieldGroupsSchema\",\n \"description\": \"An array or collection of input field groups.\",\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"/InputFieldGroupSchema\"\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "InputFieldGroupsSchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/InputFieldGroupsSchema", "required": [], "properties": [], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:outputfieldsschema", "kind": "schema_type", "key": "OutputFieldsSchema", "title": "OutputFieldsSchema", "summary": "An array or collection of output fields.", "body": "# `OutputFieldsSchema`\n\n> An array or collection of output fields.\n\n## High-level description\n\nAn array or collection of output fields.\n\n## Internals\n\nJSON Schema id `/OutputFieldsSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/OutputFieldsSchema\",\n \"description\": \"An array or collection of output fields.\",\n \"type\": \"array\",\n \"items\": {\n \"oneOf\": [\n {\n \"$ref\": \"/PlainOutputFieldSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n }\n}\n```", "usage": "", "signature": "OutputFieldsSchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/OutputFieldsSchema", "required": [], "properties": [], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:lockobjectschema", "kind": "schema_type", "key": "LockObjectSchema", "title": "LockObjectSchema", "summary": "Zapier uses this configuration to ensure this action is performed one at a time per scope (avoid concurrency).", "body": "# `LockObjectSchema`\n\n> Zapier uses this configuration to ensure this action is performed one at a time per scope (avoid concurrency).\n\n## High-level description\n\nZapier uses this configuration to ensure this action is performed one at a time per scope (avoid concurrency).\n\n## Internals\n\nJSON Schema id `/LockObjectSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: key\n key: string; // The key to use for locking. This should be unique to the operation. While actions of different integrations with the sam\n scope?: array; // By default, locks are scoped to the app. That is, all users of the app will share the same locks. If you want to restric\n timeout?: integer; // The number of seconds to hold the lock before releasing it to become accessible to other task invokes that need it. If n\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/LockObjectSchema\",\n \"description\": \"Zapier uses this configuration to ensure this action is performed one at a time per scope (avoid concurrency).\",\n \"type\": \"object\",\n \"required\": [\n \"key\"\n ],\n \"properties\": {\n \"key\": {\n \"description\": \"The key to use for locking. This should be unique to the operation. While actions of different integrations with the same key and scope will never lock each other out, actions of the same integration with the same key and scope will do. User data provided for the input fields can be used in the key with the use of the curly braces referencing. For example, to access the user data provided for the input field \\\"test_field\\\", use `{{bundle.inputData.test_field}}`. Note that a required input field should be referenced to get user data always.\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"scope\": {\n \"description\": \"By default, locks are scoped to the app. That is, all users of the app will share the same locks. If you want to restrict serial access to a specific user, auth, or account, you can set the scope to one or more of the following: 'user' - Locks based on user ids. 'auth' - Locks based on unique auth ids. 'account' - Locks for all users under a single account. You may also combine scopes. Note that \\\"app\\\" is included, always, in the scope provided. For example, a scope of ['account', 'auth'] would result to ['app', 'account', 'auth'].\",\n \"type\": \"array\",\n \"items\": {\n \"enum\": [\n \"user\",\n \"auth\",\n \"account\"\n ],\n \"type\": \"string\"\n }\n },\n \"timeout\": {\n \"description\": \"The number of seconds to hold the lock before releasing it to become accessible to other task invokes that need it. If not provided, the default set by the app will be used. It cannot be more than 180.\",\n \"type\": \"integer\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "LockObjectSchema required=[key]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/LockObjectSchema", "required": ["key"], "properties": ["key", "scope", "timeout"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:resultsschema", "kind": "schema_type", "key": "ResultsSchema", "title": "ResultsSchema", "summary": "An array of objects suitable for returning in perform calls.", "body": "# `ResultsSchema`\n\n> An array of objects suitable for returning in perform calls.\n\n## High-level description\n\nAn array of objects suitable for returning in perform calls.\n\n## Internals\n\nJSON Schema id `/ResultsSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/ResultsSchema\",\n \"description\": \"An array of objects suitable for returning in perform calls.\",\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"minProperties\": 1\n }\n}\n```", "usage": "", "signature": "ResultsSchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/ResultsSchema", "required": [], "properties": [], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:throttleobjectschema", "kind": "schema_type", "key": "ThrottleObjectSchema", "title": "ThrottleObjectSchema", "summary": "Zapier uses this configuration to apply throttling when the limit for the window is exceeded. **NOTE:** The final key used for the throttling is formed as a combination of all the configurations; key, window, limit, and scope. To share a limit across multiple actions in an integration, each should have the same configuration set without \"action\" in the scope.", "body": "# `ThrottleObjectSchema`\n\n> Zapier uses this configuration to apply throttling when the limit for the window is exceeded. **NOTE:** The final key used for the throttling is formed as a combination of all the configurations; key, window, limit, and scope. To share a limit across multiple actions in an integration, each should have the same configuration set without \"action\" in the scope.\n\n## High-level description\n\nZapier uses this configuration to apply throttling when the limit for the window is exceeded. **NOTE:** The final key used for the throttling is formed as a combination of all the configurations; key, window, limit, and scope. To share a limit across multiple actions in an integration, each should have the same configuration set without \"action\" in the scope.\n\n## Internals\n\nJSON Schema id `/ThrottleObjectSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: window, limit\n window: integer; // The timeframe, in seconds, within which the system tracks the number of invocations for an action. The number of invocat\n limit: integer; // The maximum number of invocations for an action, allowed within the timeframe window.\n key?: string; // The key to throttle with in combination with the scope. User data provided for the input fields can be used in the key w\n scope?: array; // The granularity to throttle by. You can set the scope to one or more of the following: 'user' - Throttles based on user \n retry?: boolean; // The effect of throttling on the tasks of the action. `true` means throttled tasks are automatically retried after some d\n filter?: string; // EXPERIMENTAL: Account-based attribute to override the throttle by. You can set to one of the following: \"free\", \"trial\",\n overrides?: array; // EXPERIMENTAL: Overrides the original throttle configuration based on a Zapier account attribute.\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/ThrottleObjectSchema\",\n \"description\": \"Zapier uses this configuration to apply throttling when the limit for the window is exceeded. **NOTE:** The final key used for the throttling is formed as a combination of all the configurations; key, window, limit, and scope. To share a limit across multiple actions in an integration, each should have the same configuration set without \\\"action\\\" in the scope.\",\n \"type\": \"object\",\n \"required\": [\n \"window\",\n \"limit\"\n ],\n \"properties\": {\n \"window\": {\n \"description\": \"The timeframe, in seconds, within which the system tracks the number of invocations for an action. The number of invocations begins at zero at the start of each window.\",\n \"type\": \"integer\"\n },\n \"limit\": {\n \"description\": \"The maximum number of invocations for an action, allowed within the timeframe window.\",\n \"type\": \"integer\"\n },\n \"key\": {\n \"description\": \"The key to throttle with in combination with the scope. User data provided for the input fields can be used in the key with the use of the curly braces referencing. For example, to access the user data provided for the input field \\\"test_field\\\", use `{{bundle.inputData.test_field}}`. Note that a required input field should be referenced to get user data always.\",\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"scope\": {\n \"description\": \"The granularity to throttle by. You can set the scope to one or more of the following: 'user' - Throttles based on user ids. 'auth' - Throttles based on auth ids. 'account' - Throttles based on account ids for all users under a single account. 'action' - Throttles the action it is set on separately from other actions. By default, throttling is scoped to the action and account.\",\n \"type\": \"array\",\n \"items\": {\n \"enum\": [\n \"user\",\n \"auth\",\n \"account\",\n \"action\"\n ],\n \"type\": \"string\"\n }\n },\n \"retry\": {\n \"description\": \"The effect of throttling on the tasks of the action. `true` means throttled tasks are automatically retried after some delay, while `false` means tasks are held without retry. It defaults to `true`. NOTE that it has no effect on polling triggers and should not be set.\",\n \"type\": \"boolean\"\n },\n \"filter\": {\n \"description\": \"EXPERIMENTAL: Account-based attribute to override the throttle by. You can set to one of the following: \\\"free\\\", \\\"trial\\\", \\\"paid\\\". Therefore, the throttle scope would be automatically set to \\\"account\\\" and ONLY the accounts based on the specified filter will have their requests throttled based on the throttle overrides while the rest are throttled based on the original configuration.\",\n \"type\": \"string\",\n \"enum\": [\n \"free\",\n \"trial\",\n \"paid\"\n ]\n },\n \"overrides\": {\n \"description\": \"EXPERIMENTAL: Overrides the original throttle configuration based on a Zapier account attribute.\",\n \"type\": \"array\",\n \"minItems\": 1,\n \"items\": {\n \"$ref\": \"/ThrottleOverrideObjectSchema\"\n }\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "ThrottleObjectSchema required=[window, limit]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/ThrottleObjectSchema", "required": ["window", "limit"], "properties": ["window", "limit", "key", "scope", "retry", "filter", "overrides"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:basicdisplayschema", "kind": "schema_type", "key": "BasicDisplaySchema", "title": "BasicDisplaySchema", "summary": "Represents user information for a trigger, search, or create.", "body": "# `BasicDisplaySchema`\n\n> Represents user information for a trigger, search, or create.\n\n## High-level description\n\nRepresents user information for a trigger, search, or create.\n\n## Internals\n\nJSON Schema id `/BasicDisplaySchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n label?: string; // A short label like \"New Record\" or \"Create Record in Project\". Optional if `hidden` is true.\n description?: string; // A description of what this trigger, search, or create does. Optional if `hidden` is true.\n directions?: string; // A short blurb that can explain how to get this working. EG: how and where to copy-paste a static hook URL into your appl\n hidden?: boolean; // Should this operation be unselectable by users?\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/BasicDisplaySchema\",\n \"description\": \"Represents user information for a trigger, search, or create.\",\n \"type\": \"object\",\n \"properties\": {\n \"label\": {\n \"description\": \"A short label like \\\"New Record\\\" or \\\"Create Record in Project\\\". Optional if `hidden` is true.\",\n \"type\": \"string\",\n \"minLength\": 2,\n \"maxLength\": 64,\n \"docAnnotation\": {\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"**yes** (with exceptions, see description)\"\n }\n }\n },\n \"description\": {\n \"description\": \"A description of what this trigger, search, or create does. Optional if `hidden` is true.\",\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 1000,\n \"docAnnotation\": {\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"**yes** (with exceptions, see description)\"\n }\n }\n },\n \"directions\": {\n \"description\": \"A short blurb that can explain how to get this working. EG: how and where to copy-paste a static hook URL into your application. Only evaluated for static webhooks.\",\n \"type\": \"string\",\n \"minLength\": 12,\n \"maxLength\": 1000\n },\n \"hidden\": {\n \"description\": \"Should this operation be unselectable by users?\",\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "BasicDisplaySchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/BasicDisplaySchema", "required": [], "properties": ["label", "description", "directions", "hidden"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:basicoperationschema", "kind": "schema_type", "key": "BasicOperationSchema", "title": "BasicOperationSchema", "summary": "Represents the fundamental mechanics of triggers, searches, or creates.", "body": "# `BasicOperationSchema`\n\n> Represents the fundamental mechanics of triggers, searches, or creates.\n\n## High-level description\n\nRepresents the fundamental mechanics of triggers, searches, or creates.\n\n## Internals\n\nJSON Schema id `/BasicOperationSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: perform\n resource?: /KeySchema; // Optionally reference and extends a resource. Allows Zapier to automatically tie together samples, lists and hooks, great\n perform: any; // How will Zapier get the data? This can be a function like `(z) => [{id: 123}]` or a request like `{url: 'http...'}`.\n inputFields?: /InputFieldsSchema; // What should the form a user sees and configures look like?\n inputFieldGroups?: /InputFieldGroupsSchema; // Defines groups for organizing input fields in the UI. Each group can have a key, label, and emphasis styling.\n outputFields?: /OutputFieldsSchema; // What fields of data will this return? Will use resource outputFields if missing, will also use sample if available.\n sample?: object; // What does a sample of data look like? Will use resource sample if missing. Requirement waived if `display.hidden` is tru\n lock?: /LockObjectSchema; // Zapier uses this configuration to ensure this action is performed one at a time per scope (avoid concurrency).\n throttle?: /ThrottleObjectSchema; // Zapier uses this configuration to apply throttling when the limit for the window is exceeded.\n cleanInputData?: boolean; // If true, Zapier removes empty strings, `null`, `undefined`, and empty Arrays or objects from `bundle.inputData` recursiv\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/BasicOperationSchema\",\n \"description\": \"Represents the fundamental mechanics of triggers, searches, or creates.\",\n \"type\": \"object\",\n \"required\": [\n \"perform\"\n ],\n \"properties\": {\n \"resource\": {\n \"description\": \"Optionally reference and extends a resource. Allows Zapier to automatically tie together samples, lists and hooks, greatly improving the UX. EG: if you had another trigger reusing a resource but filtering the results.\",\n \"$ref\": \"/KeySchema\"\n },\n \"perform\": {\n \"description\": \"How will Zapier get the data? This can be a function like `(z) => [{id: 123}]` or a request like `{url: 'http...'}`.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"inputFields\": {\n \"description\": \"What should the form a user sees and configures look like?\",\n \"$ref\": \"/InputFieldsSchema\"\n },\n \"inputFieldGroups\": {\n \"description\": \"Defines groups for organizing input fields in the UI. Each group can have a key, label, and emphasis styling.\",\n \"$ref\": \"/InputFieldGroupsSchema\"\n },\n \"outputFields\": {\n \"description\": \"What fields of data will this return? Will use resource outputFields if missing, will also use sample if available.\",\n \"$ref\": \"/OutputFieldsSchema\"\n },\n \"sample\": {\n \"description\": \"What does a sample of data look like? Will use resource sample if missing. Requirement waived if `display.hidden` is true or if this belongs to a resource that has a top-level sample\",\n \"type\": \"object\",\n \"minProperties\": 1,\n \"docAnnotation\": {\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"**yes** (with exceptions, see description)\"\n }\n }\n },\n \"lock\": {\n \"description\": \"Zapier uses this configuration to ensure this action is performed one at a time per scope (avoid concurrency).\",\n \"$ref\": \"/LockObjectSchema\"\n },\n \"throttle\": {\n \"description\": \"Zapier uses this configuration to apply throttling when the limit for the window is exceeded.\",\n \"$ref\": \"/ThrottleObjectSchema\"\n },\n \"cleanInputData\": {\n \"description\": \"If true, Zapier removes empty strings, `null`, `undefined`, and empty Arrays or objects from `bundle.inputData` recursively before passing it to your `perform*` function. If you want to handle empty values yourself in your code, explicitly set this to false. There is also a global flag with the same name in `App.flags`. This one takes precedence over the global one.\",\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "BasicOperationSchema required=[perform]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/BasicOperationSchema", "required": ["perform"], "properties": ["resource", "perform", "inputFields", "inputFieldGroups", "outputFields", "sample", "lock", "throttle", "cleanInputData"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:basichookoperationschema", "kind": "schema_type", "key": "BasicHookOperationSchema", "title": "BasicHookOperationSchema", "summary": "Represents the inbound mechanics of hooks with optional subscribe/unsubscribe. Defers to list for fields.", "body": "# `BasicHookOperationSchema`\n\n> Represents the inbound mechanics of hooks with optional subscribe/unsubscribe. Defers to list for fields.\n\n## High-level description\n\nRepresents the inbound mechanics of hooks with optional subscribe/unsubscribe. Defers to list for fields.\n\n## Internals\n\nJSON Schema id `/BasicHookOperationSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: perform\n type?: string; // Must be explicitly set to `\"hook\"` unless this hook is defined as part of a resource, in which case it's optional.\n resource?: /KeySchema; // Optionally reference and extends a resource. Allows Zapier to automatically tie together samples, lists and hooks, great\n perform: /FunctionSchema; // A function that processes the inbound webhook request.\n performList?: any; // Fetch a list of items on demand during testing instead of waiting for a hook. You can also consider resources and their \n canPaginate?: boolean; // Does this endpoint support pagination via temporary cursor storage?\n performSubscribe?: any; // Takes a URL and any necessary data from the user and subscribes. Note: this is required for public apps to ensure the be\n performUnsubscribe?: any; // Takes a URL and data from a previous subscribe call and unsubscribes. Note: this is required for public apps to ensure t\n inputFields?: /InputFieldsSchema; // What should the form a user sees and configures look like?\n inputFieldGroups?: /InputFieldGroupsSchema; // Defines groups for organizing input fields in the UI. Each group can have a key, label, and emphasis styling.\n outputFields?: /OutputFieldsSchema; // What fields of data will this return? Will use resource outputFields if missing, will also use sample if available.\n sample?: object; // What does a sample of data look like? Will use resource sample if missing. Requirement waived if `display.hidden` is tru\n cleanInputData?: boolean; // If true, Zapier removes empty strings, `null`, `undefined`, and empty Arrays or objects from `bundle.inputData` recursiv\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/BasicHookOperationSchema\",\n \"description\": \"Represents the inbound mechanics of hooks with optional subscribe/unsubscribe. Defers to list for fields.\",\n \"type\": \"object\",\n \"required\": [\n \"perform\"\n ],\n \"properties\": {\n \"type\": {\n \"description\": \"Must be explicitly set to `\\\"hook\\\"` unless this hook is defined as part of a resource, in which case it's optional.\",\n \"type\": \"string\",\n \"enum\": [\n \"hook\"\n ],\n \"docAnnotation\": {\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"**yes** (with exceptions, see description)\"\n }\n }\n },\n \"resource\": {\n \"description\": \"Optionally reference and extends a resource. Allows Zapier to automatically tie together samples, lists and hooks, greatly improving the UX. EG: if you had another trigger reusing a resource but filtering the results.\",\n \"$ref\": \"/KeySchema\"\n },\n \"perform\": {\n \"description\": \"A function that processes the inbound webhook request.\",\n \"$ref\": \"/FunctionSchema\"\n },\n \"performList\": {\n \"description\": \"Fetch a list of items on demand during testing instead of waiting for a hook. You can also consider resources and their built-in hook/list methods. Note: this is required for public apps to ensure the best UX for the end-user. For private apps, this is strongly recommended for testing REST Hooks. Otherwise, you can ignore warnings about this property with the `--without-style` flag during `zapier-platform push`.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ],\n \"docAnnotation\": {\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"**yes** (with exceptions, see description)\"\n }\n }\n },\n \"canPaginate\": {\n \"description\": \"Does this endpoint support pagination via temporary cursor storage?\",\n \"type\": \"boolean\"\n },\n \"performSubscribe\": {\n \"description\": \"Takes a URL and any necessary data from the user and subscribes. Note: this is required for public apps to ensure the best UX for the end-user. For private apps, this is strongly recommended for testing REST Hooks. Otherwise, you can ignore warnings about this property with the `--without-style` flag during `zapier-platform push`.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ],\n \"docAnnotation\": {\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"**yes** (with exceptions, see description)\"\n }\n }\n },\n \"performUnsubscribe\": {\n \"description\": \"Takes a URL and data from a previous subscribe call and unsubscribes. Note: this is required for public apps to ensure the best UX for the end-user. For private apps, this is strongly recommended for testing REST Hooks. Otherwise, you can ignore warnings about this property with the `--without-style` flag during `zapier-platform push`.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ],\n \"docAnnotation\": {\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"**yes** (with exceptions, see description)\"\n }\n }\n },\n \"inputFields\": {\n \"description\": \"What should the form a user sees and configures look like?\",\n \"$ref\": \"/InputFieldsSchema\"\n },\n \"inputFieldGroups\": {\n \"description\": \"Defines groups for organizing input fields in the UI. Each group can have a key, label, and emphasis styling.\",\n \"$ref\": \"/InputFieldGroupsSchema\"\n },\n \"outputFields\": {\n \"description\": \"What fields of data will this return? Will use resource outputFields if missing, will also use sample if available.\",\n \"$ref\": \"/OutputFieldsSchema\"\n },\n \"sample\": {\n \"description\": \"What does a sample of data look like? Will use resource sample if missing. Requirement waived if `display.hidden` is true or if this belongs to a resource that has a top-level sample\",\n \"type\": \"object\",\n \"minProperties\": 1,\n \"docAnnotation\": {\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"**yes** (with exceptions, see description)\"\n }\n }\n },\n \"cleanInputData\": {\n \"description\": \"If true, Zapier removes empty strings, `null`, `undefined`, and empty Arrays or objects from `bundle.inputData` recursively before passing it to your `perform*` function. If you want to handle empty values yourself in your code, explicitly set this to false. There is also a global flag with the same name in `App.flags`. This one takes precedence over the global one.\",\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "BasicHookOperationSchema required=[perform]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/BasicHookOperationSchema", "required": ["perform"], "properties": ["type", "resource", "perform", "performList", "canPaginate", "performSubscribe", "performUnsubscribe", "inputFields", "inputFieldGroups", "outputFields", "sample", "cleanInputData"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:basicpollingoperationschema", "kind": "schema_type", "key": "BasicPollingOperationSchema", "title": "BasicPollingOperationSchema", "summary": "Represents the fundamental mechanics of a trigger.", "body": "# `BasicPollingOperationSchema`\n\n> Represents the fundamental mechanics of a trigger.\n\n## High-level description\n\nRepresents the fundamental mechanics of a trigger.\n\n## Internals\n\nJSON Schema id `/BasicPollingOperationSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: perform\n type?: string; // Clarify how this operation works (polling == pull or hook == push).\n resource?: /KeySchema; // Optionally reference and extends a resource. Allows Zapier to automatically tie together samples, lists and hooks, great\n perform: any; // How will Zapier get the data? This can be a function like `(z) => [{id: 123}]` or a request like `{url: 'http...'}`.\n canPaginate?: boolean; // Does this endpoint support pagination via temporary cursor storage?\n inputFields?: /InputFieldsSchema; // What should the form a user sees and configures look like?\n inputFieldGroups?: /InputFieldGroupsSchema; // Defines groups for organizing input fields in the UI. Each group can have a key, label, and emphasis styling.\n outputFields?: /OutputFieldsSchema; // What fields of data will this return? Will use resource outputFields if missing, will also use sample if available.\n sample?: object; // What does a sample of data look like? Will use resource sample if missing. Requirement waived if `display.hidden` is tru\n throttle?: /ThrottleObjectSchema; // Zapier uses this configuration to apply throttling when the limit for the window is exceeded.\n cleanInputData?: boolean; // If true, Zapier removes empty strings, `null`, `undefined`, and empty Arrays or objects from `bundle.inputData` recursiv\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/BasicPollingOperationSchema\",\n \"description\": \"Represents the fundamental mechanics of a trigger.\",\n \"type\": \"object\",\n \"required\": [\n \"perform\"\n ],\n \"properties\": {\n \"type\": {\n \"description\": \"Clarify how this operation works (polling == pull or hook == push).\",\n \"type\": \"string\",\n \"default\": \"polling\",\n \"enum\": [\n \"polling\"\n ]\n },\n \"resource\": {\n \"description\": \"Optionally reference and extends a resource. Allows Zapier to automatically tie together samples, lists and hooks, greatly improving the UX. EG: if you had another trigger reusing a resource but filtering the results.\",\n \"$ref\": \"/KeySchema\"\n },\n \"perform\": {\n \"description\": \"How will Zapier get the data? This can be a function like `(z) => [{id: 123}]` or a request like `{url: 'http...'}`.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"canPaginate\": {\n \"description\": \"Does this endpoint support pagination via temporary cursor storage?\",\n \"type\": \"boolean\"\n },\n \"inputFields\": {\n \"description\": \"What should the form a user sees and configures look like?\",\n \"$ref\": \"/InputFieldsSchema\"\n },\n \"inputFieldGroups\": {\n \"description\": \"Defines groups for organizing input fields in the UI. Each group can have a key, label, and emphasis styling.\",\n \"$ref\": \"/InputFieldGroupsSchema\"\n },\n \"outputFields\": {\n \"description\": \"What fields of data will this return? Will use resource outputFields if missing, will also use sample if available.\",\n \"$ref\": \"/OutputFieldsSchema\"\n },\n \"sample\": {\n \"description\": \"What does a sample of data look like? Will use resource sample if missing. Requirement waived if `display.hidden` is true or if this belongs to a resource that has a top-level sample\",\n \"type\": \"object\",\n \"minProperties\": 1,\n \"docAnnotation\": {\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"**yes** (with exceptions, see description)\"\n }\n }\n },\n \"throttle\": {\n \"description\": \"Zapier uses this configuration to apply throttling when the limit for the window is exceeded.\",\n \"$ref\": \"/ThrottleObjectSchema\"\n },\n \"cleanInputData\": {\n \"description\": \"If true, Zapier removes empty strings, `null`, `undefined`, and empty Arrays or objects from `bundle.inputData` recursively before passing it to your `perform*` function. If you want to handle empty values yourself in your code, explicitly set this to false. There is also a global flag with the same name in `App.flags`. This one takes precedence over the global one.\",\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "BasicPollingOperationSchema required=[perform]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/BasicPollingOperationSchema", "required": ["perform"], "properties": ["type", "resource", "perform", "canPaginate", "inputFields", "inputFieldGroups", "outputFields", "sample", "throttle", "cleanInputData"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:basicactionoperationschema", "kind": "schema_type", "key": "BasicActionOperationSchema", "title": "BasicActionOperationSchema", "summary": "Represents the fundamental mechanics of a search/create.", "body": "# `BasicActionOperationSchema`\n\n> Represents the fundamental mechanics of a search/create.\n\n## High-level description\n\nRepresents the fundamental mechanics of a search/create.\n\n## Internals\n\nJSON Schema id `/BasicActionOperationSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: perform\n resource?: /KeySchema; // Optionally reference and extends a resource. Allows Zapier to automatically tie together samples, lists and hooks, great\n perform: any; // How will Zapier get the data? This can be a function like `(z) => [{id: 123}]` or a request like `{url: 'http...'}`.\n performResume?: /FunctionSchema; // A function that parses data from a perform (which uses z.generateCallbackUrl()) and callback request to resume this acti\n performGet?: any; // How will Zapier get a single record? If you find yourself reaching for this - consider resources and their built-in get \n inputFields?: /InputFieldsSchema; // What should the form a user sees and configures look like?\n inputFieldGroups?: /InputFieldGroupsSchema; // Defines groups for organizing input fields in the UI. Each group can have a key, label, and emphasis styling.\n outputFields?: /OutputFieldsSchema; // What fields of data will this return? Will use resource outputFields if missing, will also use sample if available.\n sample?: object; // What does a sample of data look like? Will use resource sample if missing. Requirement waived if `display.hidden` is tru\n lock?: /LockObjectSchema; // Zapier uses this configuration to ensure this action is performed one at a time per scope (avoid concurrency).\n throttle?: /ThrottleObjectSchema; // Zapier uses this configuration to apply throttling when the limit for the window is exceeded.\n cleanInputData?: boolean; // If true, Zapier removes empty strings, `null`, `undefined`, and empty Arrays or objects from `bundle.inputData` recursiv\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/BasicActionOperationSchema\",\n \"description\": \"Represents the fundamental mechanics of a search/create.\",\n \"type\": \"object\",\n \"required\": [\n \"perform\"\n ],\n \"properties\": {\n \"resource\": {\n \"description\": \"Optionally reference and extends a resource. Allows Zapier to automatically tie together samples, lists and hooks, greatly improving the UX. EG: if you had another trigger reusing a resource but filtering the results.\",\n \"$ref\": \"/KeySchema\"\n },\n \"perform\": {\n \"description\": \"How will Zapier get the data? This can be a function like `(z) => [{id: 123}]` or a request like `{url: 'http...'}`.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"performResume\": {\n \"description\": \"A function that parses data from a perform (which uses z.generateCallbackUrl()) and callback request to resume this action.\",\n \"$ref\": \"/FunctionSchema\"\n },\n \"performGet\": {\n \"description\": \"How will Zapier get a single record? If you find yourself reaching for this - consider resources and their built-in get methods.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"inputFields\": {\n \"description\": \"What should the form a user sees and configures look like?\",\n \"$ref\": \"/InputFieldsSchema\"\n },\n \"inputFieldGroups\": {\n \"description\": \"Defines groups for organizing input fields in the UI. Each group can have a key, label, and emphasis styling.\",\n \"$ref\": \"/InputFieldGroupsSchema\"\n },\n \"outputFields\": {\n \"description\": \"What fields of data will this return? Will use resource outputFields if missing, will also use sample if available.\",\n \"$ref\": \"/OutputFieldsSchema\"\n },\n \"sample\": {\n \"description\": \"What does a sample of data look like? Will use resource sample if missing. Requirement waived if `display.hidden` is true or if this belongs to a resource that has a top-level sample\",\n \"type\": \"object\",\n \"minProperties\": 1,\n \"docAnnotation\": {\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"**yes** (with exceptions, see description)\"\n }\n }\n },\n \"lock\": {\n \"description\": \"Zapier uses this configuration to ensure this action is performed one at a time per scope (avoid concurrency).\",\n \"$ref\": \"/LockObjectSchema\"\n },\n \"throttle\": {\n \"description\": \"Zapier uses this configuration to apply throttling when the limit for the window is exceeded.\",\n \"$ref\": \"/ThrottleObjectSchema\"\n },\n \"cleanInputData\": {\n \"description\": \"If true, Zapier removes empty strings, `null`, `undefined`, and empty Arrays or objects from `bundle.inputData` recursively before passing it to your `perform*` function. If you want to handle empty values yourself in your code, explicitly set this to false. There is also a global flag with the same name in `App.flags`. This one takes precedence over the global one.\",\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "BasicActionOperationSchema required=[perform]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/BasicActionOperationSchema", "required": ["perform"], "properties": ["resource", "perform", "performResume", "performGet", "inputFields", "inputFieldGroups", "outputFields", "sample", "lock", "throttle", "cleanInputData"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:resourcemethodgetschema", "kind": "schema_type", "key": "ResourceMethodGetSchema", "title": "ResourceMethodGetSchema", "summary": "How will we get a single object given a unique identifier/id?", "body": "# `ResourceMethodGetSchema`\n\n> How will we get a single object given a unique identifier/id?\n\n## High-level description\n\nHow will we get a single object given a unique identifier/id?\n\n## Internals\n\nJSON Schema id `/ResourceMethodGetSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: display, operation\n display: /BasicDisplaySchema; // Define how this get method will be exposed in the UI.\n operation: /BasicOperationSchema; // Define how this get method will work.\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/ResourceMethodGetSchema\",\n \"description\": \"How will we get a single object given a unique identifier/id?\",\n \"type\": \"object\",\n \"required\": [\n \"display\",\n \"operation\"\n ],\n \"properties\": {\n \"display\": {\n \"description\": \"Define how this get method will be exposed in the UI.\",\n \"$ref\": \"/BasicDisplaySchema\"\n },\n \"operation\": {\n \"description\": \"Define how this get method will work.\",\n \"$ref\": \"/BasicOperationSchema\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "ResourceMethodGetSchema required=[display, operation]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/ResourceMethodGetSchema", "required": ["display", "operation"], "properties": ["display", "operation"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:resourcemethodhookschema", "kind": "schema_type", "key": "ResourceMethodHookSchema", "title": "ResourceMethodHookSchema", "summary": "How will we get notified of new objects? Will be turned into a trigger automatically.", "body": "# `ResourceMethodHookSchema`\n\n> How will we get notified of new objects? Will be turned into a trigger automatically.\n\n## High-level description\n\nHow will we get notified of new objects? Will be turned into a trigger automatically.\n\n## Internals\n\nJSON Schema id `/ResourceMethodHookSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: display, operation\n display: /BasicDisplaySchema; // Define how this hook/trigger method will be exposed in the UI.\n operation: /BasicHookOperationSchema; // Define how this hook/trigger method will work.\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/ResourceMethodHookSchema\",\n \"description\": \"How will we get notified of new objects? Will be turned into a trigger automatically.\",\n \"type\": \"object\",\n \"required\": [\n \"display\",\n \"operation\"\n ],\n \"properties\": {\n \"display\": {\n \"description\": \"Define how this hook/trigger method will be exposed in the UI.\",\n \"$ref\": \"/BasicDisplaySchema\"\n },\n \"operation\": {\n \"description\": \"Define how this hook/trigger method will work.\",\n \"$ref\": \"/BasicHookOperationSchema\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "ResourceMethodHookSchema required=[display, operation]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/ResourceMethodHookSchema", "required": ["display", "operation"], "properties": ["display", "operation"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:resourcemethodlistschema", "kind": "schema_type", "key": "ResourceMethodListSchema", "title": "ResourceMethodListSchema", "summary": "How will we get a list of new objects? Will be turned into a trigger automatically.", "body": "# `ResourceMethodListSchema`\n\n> How will we get a list of new objects? Will be turned into a trigger automatically.\n\n## High-level description\n\nHow will we get a list of new objects? Will be turned into a trigger automatically.\n\n## Internals\n\nJSON Schema id `/ResourceMethodListSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: display, operation\n display: /BasicDisplaySchema; // Define how this list/trigger method will be exposed in the UI.\n operation: /BasicPollingOperationSchema; // Define how this list/trigger method will work.\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/ResourceMethodListSchema\",\n \"description\": \"How will we get a list of new objects? Will be turned into a trigger automatically.\",\n \"type\": \"object\",\n \"required\": [\n \"display\",\n \"operation\"\n ],\n \"properties\": {\n \"display\": {\n \"description\": \"Define how this list/trigger method will be exposed in the UI.\",\n \"$ref\": \"/BasicDisplaySchema\"\n },\n \"operation\": {\n \"description\": \"Define how this list/trigger method will work.\",\n \"$ref\": \"/BasicPollingOperationSchema\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "ResourceMethodListSchema required=[display, operation]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/ResourceMethodListSchema", "required": ["display", "operation"], "properties": ["display", "operation"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:resourcemethodsearchschema", "kind": "schema_type", "key": "ResourceMethodSearchSchema", "title": "ResourceMethodSearchSchema", "summary": "How will we find a specific object given filters or search terms? Will be turned into a search automatically.", "body": "# `ResourceMethodSearchSchema`\n\n> How will we find a specific object given filters or search terms? Will be turned into a search automatically.\n\n## High-level description\n\nHow will we find a specific object given filters or search terms? Will be turned into a search automatically.\n\n## Internals\n\nJSON Schema id `/ResourceMethodSearchSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: display, operation\n display: /BasicDisplaySchema; // Define how this search method will be exposed in the UI.\n operation: /BasicActionOperationSchema; // Define how this search method will work.\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/ResourceMethodSearchSchema\",\n \"description\": \"How will we find a specific object given filters or search terms? Will be turned into a search automatically.\",\n \"type\": \"object\",\n \"required\": [\n \"display\",\n \"operation\"\n ],\n \"properties\": {\n \"display\": {\n \"description\": \"Define how this search method will be exposed in the UI.\",\n \"$ref\": \"/BasicDisplaySchema\"\n },\n \"operation\": {\n \"description\": \"Define how this search method will work.\",\n \"$ref\": \"/BasicActionOperationSchema\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "ResourceMethodSearchSchema required=[display, operation]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/ResourceMethodSearchSchema", "required": ["display", "operation"], "properties": ["display", "operation"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:resourcemethodcreateschema", "kind": "schema_type", "key": "ResourceMethodCreateSchema", "title": "ResourceMethodCreateSchema", "summary": "How will we find create a specific object given inputs? Will be turned into a create automatically.", "body": "# `ResourceMethodCreateSchema`\n\n> How will we find create a specific object given inputs? Will be turned into a create automatically.\n\n## High-level description\n\nHow will we find create a specific object given inputs? Will be turned into a create automatically.\n\n## Internals\n\nJSON Schema id `/ResourceMethodCreateSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: display, operation\n display: /BasicDisplaySchema; // Define how this create method will be exposed in the UI.\n operation: /BasicActionOperationSchema; // Define how this create method will work.\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/ResourceMethodCreateSchema\",\n \"description\": \"How will we find create a specific object given inputs? Will be turned into a create automatically.\",\n \"type\": \"object\",\n \"required\": [\n \"display\",\n \"operation\"\n ],\n \"properties\": {\n \"display\": {\n \"description\": \"Define how this create method will be exposed in the UI.\",\n \"$ref\": \"/BasicDisplaySchema\"\n },\n \"operation\": {\n \"description\": \"Define how this create method will work.\",\n \"$ref\": \"/BasicActionOperationSchema\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "ResourceMethodCreateSchema required=[display, operation]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/ResourceMethodCreateSchema", "required": ["display", "operation"], "properties": ["display", "operation"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:resourceschema", "kind": "schema_type", "key": "ResourceSchema", "title": "ResourceSchema", "summary": "Represents a resource, which will in turn power triggers, searches, or creates.", "body": "# `ResourceSchema`\n\n> Represents a resource, which will in turn power triggers, searches, or creates.\n\n## High-level description\n\nRepresents a resource, which will in turn power triggers, searches, or creates.\n\n## Internals\n\nJSON Schema id `/ResourceSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: key, noun\n key: /KeySchema; // A key to uniquely identify this resource.\n noun: string; // A noun for this resource that completes the sentence \"create a new XXX\".\n get?: /ResourceMethodGetSchema; // How will we get a single object given a unique identifier/id?\n hook?: /ResourceMethodHookSchema; // How will we get notified of new objects? Will be turned into a trigger automatically.\n list?: /ResourceMethodListSchema; // How will we get a list of new objects? Will be turned into a trigger automatically.\n search?: /ResourceMethodSearchSchema; // How will we find a specific object given filters or search terms? Will be turned into a search automatically.\n create?: /ResourceMethodCreateSchema; // How will we find create a specific object given inputs? Will be turned into a create automatically.\n outputFields?: /OutputFieldsSchema; // What fields of data will this return?\n sample?: object; // What does a sample of data look like?\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/ResourceSchema\",\n \"description\": \"Represents a resource, which will in turn power triggers, searches, or creates.\",\n \"type\": \"object\",\n \"required\": [\n \"key\",\n \"noun\"\n ],\n \"properties\": {\n \"key\": {\n \"description\": \"A key to uniquely identify this resource.\",\n \"$ref\": \"/KeySchema\"\n },\n \"noun\": {\n \"description\": \"A noun for this resource that completes the sentence \\\"create a new XXX\\\".\",\n \"type\": \"string\",\n \"minLength\": 2,\n \"maxLength\": 255\n },\n \"get\": {\n \"description\": \"How will we get a single object given a unique identifier/id?\",\n \"$ref\": \"/ResourceMethodGetSchema\"\n },\n \"hook\": {\n \"description\": \"How will we get notified of new objects? Will be turned into a trigger automatically.\",\n \"$ref\": \"/ResourceMethodHookSchema\"\n },\n \"list\": {\n \"description\": \"How will we get a list of new objects? Will be turned into a trigger automatically.\",\n \"$ref\": \"/ResourceMethodListSchema\"\n },\n \"search\": {\n \"description\": \"How will we find a specific object given filters or search terms? Will be turned into a search automatically.\",\n \"$ref\": \"/ResourceMethodSearchSchema\"\n },\n \"create\": {\n \"description\": \"How will we find create a specific object given inputs? Will be turned into a create automatically.\",\n \"$ref\": \"/ResourceMethodCreateSchema\"\n },\n \"outputFields\": {\n \"description\": \"What fields of data will this return?\",\n \"$ref\": \"/OutputFieldsSchema\"\n },\n \"sample\": {\n \"description\": \"What does a sample of data look like?\",\n \"type\": \"object\",\n \"minProperties\": 1\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "ResourceSchema required=[key, noun]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/ResourceSchema", "required": ["key", "noun"], "properties": ["key", "noun", "get", "hook", "list", "search", "create", "outputFields", "sample"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:bulkreadschema", "kind": "schema_type", "key": "BulkReadSchema", "title": "BulkReadSchema", "summary": "How will Zapier fetch resources from your application?", "body": "# `BulkReadSchema`\n\n> How will Zapier fetch resources from your application?\n\n## High-level description\n\nHow will Zapier fetch resources from your application?\n\n## Internals\n\nJSON Schema id `/BulkReadSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: key, noun, display, operation\n key: /KeySchema; // A key to uniquely identify a record.\n noun: string; // A noun for this read that completes the sentence \"reads all of the XXX\".\n display: /BasicDisplaySchema; // Configures the UI for this read bulk.\n operation: /BasicActionOperationSchema; // Powers the functionality for this read bulk.\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/BulkReadSchema\",\n \"description\": \"How will Zapier fetch resources from your application?\",\n \"type\": \"object\",\n \"required\": [\n \"key\",\n \"noun\",\n \"display\",\n \"operation\"\n ],\n \"properties\": {\n \"key\": {\n \"description\": \"A key to uniquely identify a record.\",\n \"$ref\": \"/KeySchema\"\n },\n \"noun\": {\n \"description\": \"A noun for this read that completes the sentence \\\"reads all of the XXX\\\".\",\n \"type\": \"string\",\n \"minLength\": 2,\n \"maxLength\": 255\n },\n \"display\": {\n \"description\": \"Configures the UI for this read bulk.\",\n \"$ref\": \"/BasicDisplaySchema\"\n },\n \"operation\": {\n \"description\": \"Powers the functionality for this read bulk.\",\n \"$ref\": \"/BasicActionOperationSchema\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "BulkReadSchema required=[key, noun, display, operation]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/BulkReadSchema", "required": ["key", "noun", "display", "operation"], "properties": ["key", "noun", "display", "operation"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:basichooktopolloperationschema", "kind": "schema_type", "key": "BasicHookToPollOperationSchema", "title": "BasicHookToPollOperationSchema", "summary": "Represents the inbound mechanics of hook to poll style triggers. Defers to list for fields.", "body": "# `BasicHookToPollOperationSchema`\n\n> Represents the inbound mechanics of hook to poll style triggers. Defers to list for fields.\n\n## High-level description\n\nRepresents the inbound mechanics of hook to poll style triggers. Defers to list for fields.\n\n## Internals\n\nJSON Schema id `/BasicHookToPollOperationSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: performList, performSubscribe, performUnsubscribe\n type?: string; // Must be explicitly set to `\"hook_to_poll\"`.\n performList: any; // Similar a polling trigger, but checks for new data when a webhook is received, instead of every few minutes\n canPaginate?: boolean; // Does this endpoint support pagination via temporary cursor storage?\n performSubscribe: any; // Takes a URL and any necessary data from the user and subscribes. \n performUnsubscribe: any; // Takes a URL and data from a previous subscribe call and unsubscribes. \n inputFields?: /InputFieldsSchema; // What should the form a user sees and configures look like?\n inputFieldGroups?: /InputFieldGroupsSchema; // Defines groups for organizing input fields in the UI. Each group can have a key, label, and emphasis styling.\n outputFields?: /OutputFieldsSchema; // What fields of data will this return? Will use resource outputFields if missing, will also use sample if available.\n sample?: object; // What does a sample of data look like? Will use resource sample if missing. Requirement waived if `display.hidden` is tru\n cleanInputData?: boolean; // If true, Zapier removes empty strings, `null`, `undefined`, and empty Arrays or objects from `bundle.inputData` recursiv\n maxPollingDelay?: integer; // The maximum amount of time to wait between polling requests in seconds. Minimum value is 20s and will default to 20 if n\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/BasicHookToPollOperationSchema\",\n \"description\": \"Represents the inbound mechanics of hook to poll style triggers. Defers to list for fields.\",\n \"type\": \"object\",\n \"required\": [\n \"performList\",\n \"performSubscribe\",\n \"performUnsubscribe\"\n ],\n \"properties\": {\n \"type\": {\n \"description\": \"Must be explicitly set to `\\\"hook_to_poll\\\"`.\",\n \"type\": \"string\",\n \"enum\": [\n \"hook_to_poll\"\n ],\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"**yes** (with exceptions, see description)\"\n }\n },\n \"performList\": {\n \"description\": \"Similar a polling trigger, but checks for new data when a webhook is received, instead of every few minutes\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"canPaginate\": {\n \"description\": \"Does this endpoint support pagination via temporary cursor storage?\",\n \"type\": \"boolean\"\n },\n \"performSubscribe\": {\n \"description\": \"Takes a URL and any necessary data from the user and subscribes. \",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"performUnsubscribe\": {\n \"description\": \"Takes a URL and data from a previous subscribe call and unsubscribes. \",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"inputFields\": {\n \"description\": \"What should the form a user sees and configures look like?\",\n \"$ref\": \"/InputFieldsSchema\"\n },\n \"inputFieldGroups\": {\n \"description\": \"Defines groups for organizing input fields in the UI. Each group can have a key, label, and emphasis styling.\",\n \"$ref\": \"/InputFieldGroupsSchema\"\n },\n \"outputFields\": {\n \"description\": \"What fields of data will this return? Will use resource outputFields if missing, will also use sample if available.\",\n \"$ref\": \"/OutputFieldsSchema\"\n },\n \"sample\": {\n \"description\": \"What does a sample of data look like? Will use resource sample if missing. Requirement waived if `display.hidden` is true or if this belongs to a resource that has a top-level sample\",\n \"type\": \"object\",\n \"minProperties\": 1,\n \"docAnnotation\": {\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"**yes** (with exceptions, see description)\"\n }\n }\n },\n \"cleanInputData\": {\n \"description\": \"If true, Zapier removes empty strings, `null`, `undefined`, and empty Arrays or objects from `bundle.inputData` recursively before passing it to your `perform*` function. If you want to handle empty values yourself in your code, explicitly set this to false. There is also a global flag with the same name in `App.flags`. This one takes precedence over the global one.\",\n \"type\": \"boolean\"\n },\n \"maxPollingDelay\": {\n \"description\": \"The maximum amount of time to wait between polling requests in seconds. Minimum value is 20s and will default to 20 if not set, or set to a lower value.\",\n \"type\": \"integer\"\n }\n },\n \"additionalProperties\": false,\n \"docAnnotation\": {\n \"hide\": true\n }\n}\n```", "usage": "", "signature": "BasicHookToPollOperationSchema required=[performList, performSubscribe, performUnsubscribe]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/BasicHookToPollOperationSchema", "required": ["performList", "performSubscribe", "performUnsubscribe"], "properties": ["type", "performList", "canPaginate", "performSubscribe", "performUnsubscribe", "inputFields", "inputFieldGroups", "outputFields", "sample", "cleanInputData", "maxPollingDelay"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:triggerschema", "kind": "schema_type", "key": "TriggerSchema", "title": "TriggerSchema", "summary": "How will Zapier get notified of new objects?", "body": "# `TriggerSchema`\n\n> How will Zapier get notified of new objects?\n\n## High-level description\n\nHow will Zapier get notified of new objects?\n\n## Internals\n\nJSON Schema id `/TriggerSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: key, noun, display, operation\n key: /KeySchema; // A key to uniquely identify this trigger.\n noun: string; // A noun for this trigger that completes the sentence \"triggers on a new XXX\".\n display: /BasicDisplaySchema; // Configures the UI for this trigger.\n operation: any; // Powers the functionality for this trigger.\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/TriggerSchema\",\n \"description\": \"How will Zapier get notified of new objects?\",\n \"type\": \"object\",\n \"required\": [\n \"key\",\n \"noun\",\n \"display\",\n \"operation\"\n ],\n \"properties\": {\n \"key\": {\n \"description\": \"A key to uniquely identify this trigger.\",\n \"$ref\": \"/KeySchema\"\n },\n \"noun\": {\n \"description\": \"A noun for this trigger that completes the sentence \\\"triggers on a new XXX\\\".\",\n \"type\": \"string\",\n \"minLength\": 2,\n \"maxLength\": 255\n },\n \"display\": {\n \"description\": \"Configures the UI for this trigger.\",\n \"$ref\": \"/BasicDisplaySchema\"\n },\n \"operation\": {\n \"description\": \"Powers the functionality for this trigger.\",\n \"anyOf\": [\n {\n \"$ref\": \"/BasicPollingOperationSchema\"\n },\n {\n \"$ref\": \"/BasicHookOperationSchema\"\n },\n {\n \"$ref\": \"/BasicHookToPollOperationSchema\"\n }\n ]\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "TriggerSchema required=[key, noun, display, operation]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/TriggerSchema", "required": ["key", "noun", "display", "operation"], "properties": ["key", "noun", "display", "operation"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:basicsearchoperationschema", "kind": "schema_type", "key": "BasicSearchOperationSchema", "title": "BasicSearchOperationSchema", "summary": "Represents the fundamental mechanics of a search.", "body": "# `BasicSearchOperationSchema`\n\n> Represents the fundamental mechanics of a search.\n\n## High-level description\n\nRepresents the fundamental mechanics of a search.\n\n## Internals\n\nJSON Schema id `/BasicSearchOperationSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: perform\n resource?: /KeySchema; // Optionally reference and extends a resource. Allows Zapier to automatically tie together samples, lists and hooks, great\n perform: any; // How will Zapier get the data? This can be a function like `(z) => [{id: 123}]` or a request like `{url: 'http...'}`.\n performResume?: /FunctionSchema; // A function that parses data from a perform (which uses z.generateCallbackUrl()) and callback request to resume this acti\n performGet?: any; // How will Zapier get a single record? If you find yourself reaching for this - consider resources and their built-in get \n canPaginate?: boolean; // Does this search support pagination?\n inputFields?: /InputFieldsSchema; // What should the form a user sees and configures look like?\n inputFieldGroups?: /InputFieldGroupsSchema; // Defines groups for organizing input fields in the UI. Each group can have a key, label, and emphasis styling.\n outputFields?: /OutputFieldsSchema; // What fields of data will this return? Will use resource outputFields if missing, will also use sample if available.\n sample?: object; // What does a sample of data look like? Will use resource sample if missing. Requirement waived if `display.hidden` is tru\n lock?: /LockObjectSchema; // Zapier uses this configuration to ensure this action is performed one at a time per scope (avoid concurrency).\n throttle?: /ThrottleObjectSchema; // Zapier uses this configuration to apply throttling when the limit for the window is exceeded.\n cleanInputData?: boolean; // If true, Zapier removes empty strings, `null`, `undefined`, and empty Arrays or objects from `bundle.inputData` recursiv\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/BasicSearchOperationSchema\",\n \"description\": \"Represents the fundamental mechanics of a search.\",\n \"type\": \"object\",\n \"required\": [\n \"perform\"\n ],\n \"properties\": {\n \"resource\": {\n \"description\": \"Optionally reference and extends a resource. Allows Zapier to automatically tie together samples, lists and hooks, greatly improving the UX. EG: if you had another trigger reusing a resource but filtering the results.\",\n \"$ref\": \"/KeySchema\"\n },\n \"perform\": {\n \"description\": \"How will Zapier get the data? This can be a function like `(z) => [{id: 123}]` or a request like `{url: 'http...'}`.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"performResume\": {\n \"description\": \"A function that parses data from a perform (which uses z.generateCallbackUrl()) and callback request to resume this action.\",\n \"$ref\": \"/FunctionSchema\"\n },\n \"performGet\": {\n \"description\": \"How will Zapier get a single record? If you find yourself reaching for this - consider resources and their built-in get methods.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"canPaginate\": {\n \"description\": \"Does this search support pagination?\",\n \"type\": \"boolean\"\n },\n \"inputFields\": {\n \"description\": \"What should the form a user sees and configures look like?\",\n \"$ref\": \"/InputFieldsSchema\"\n },\n \"inputFieldGroups\": {\n \"description\": \"Defines groups for organizing input fields in the UI. Each group can have a key, label, and emphasis styling.\",\n \"$ref\": \"/InputFieldGroupsSchema\"\n },\n \"outputFields\": {\n \"description\": \"What fields of data will this return? Will use resource outputFields if missing, will also use sample if available.\",\n \"$ref\": \"/OutputFieldsSchema\"\n },\n \"sample\": {\n \"description\": \"What does a sample of data look like? Will use resource sample if missing. Requirement waived if `display.hidden` is true or if this belongs to a resource that has a top-level sample\",\n \"type\": \"object\",\n \"minProperties\": 1,\n \"docAnnotation\": {\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"**yes** (with exceptions, see description)\"\n }\n }\n },\n \"lock\": {\n \"description\": \"Zapier uses this configuration to ensure this action is performed one at a time per scope (avoid concurrency).\",\n \"$ref\": \"/LockObjectSchema\"\n },\n \"throttle\": {\n \"description\": \"Zapier uses this configuration to apply throttling when the limit for the window is exceeded.\",\n \"$ref\": \"/ThrottleObjectSchema\"\n },\n \"cleanInputData\": {\n \"description\": \"If true, Zapier removes empty strings, `null`, `undefined`, and empty Arrays or objects from `bundle.inputData` recursively before passing it to your `perform*` function. If you want to handle empty values yourself in your code, explicitly set this to false. There is also a global flag with the same name in `App.flags`. This one takes precedence over the global one.\",\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "BasicSearchOperationSchema required=[perform]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/BasicSearchOperationSchema", "required": ["perform"], "properties": ["resource", "perform", "performResume", "performGet", "canPaginate", "inputFields", "inputFieldGroups", "outputFields", "sample", "lock", "throttle", "cleanInputData"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:searchschema", "kind": "schema_type", "key": "SearchSchema", "title": "SearchSchema", "summary": "How will Zapier search for existing objects?", "body": "# `SearchSchema`\n\n> How will Zapier search for existing objects?\n\n## High-level description\n\nHow will Zapier search for existing objects?\n\n## Internals\n\nJSON Schema id `/SearchSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: key, noun, display, operation\n key: /KeySchema; // A key to uniquely identify this search.\n noun: string; // A noun for this search that completes the sentence \"finds a specific XXX\".\n display: /BasicDisplaySchema; // Configures the UI for this search.\n operation: /BasicSearchOperationSchema; // Powers the functionality for this search.\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/SearchSchema\",\n \"description\": \"How will Zapier search for existing objects?\",\n \"type\": \"object\",\n \"required\": [\n \"key\",\n \"noun\",\n \"display\",\n \"operation\"\n ],\n \"properties\": {\n \"key\": {\n \"description\": \"A key to uniquely identify this search.\",\n \"$ref\": \"/KeySchema\"\n },\n \"noun\": {\n \"description\": \"A noun for this search that completes the sentence \\\"finds a specific XXX\\\".\",\n \"type\": \"string\",\n \"minLength\": 2,\n \"maxLength\": 255\n },\n \"display\": {\n \"description\": \"Configures the UI for this search.\",\n \"$ref\": \"/BasicDisplaySchema\"\n },\n \"operation\": {\n \"description\": \"Powers the functionality for this search.\",\n \"$ref\": \"/BasicSearchOperationSchema\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "SearchSchema required=[key, noun, display, operation]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/SearchSchema", "required": ["key", "noun", "display", "operation"], "properties": ["key", "noun", "display", "operation"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:bufferconfigschema", "kind": "schema_type", "key": "BufferConfigSchema", "title": "BufferConfigSchema", "summary": "Currently an **internal-only** feature. Zapier uses this configuration for creating objects in bulk.", "body": "# `BufferConfigSchema`\n\n> Currently an **internal-only** feature. Zapier uses this configuration for creating objects in bulk.\n\n## High-level description\n\nCurrently an **internal-only** feature. Zapier uses this configuration for creating objects in bulk.\n\n## Internals\n\nJSON Schema id `/BufferConfigSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: groupedBy, limit\n groupedBy: array; // The list of keys of input fields to group bulk-create with. The actual user data provided for the fields will be used du\n limit: integer; // The maximum number of items to call `performBuffer` with. **Note** that it is capped by the platform to prevent exceedin\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/BufferConfigSchema\",\n \"description\": \"Currently an **internal-only** feature. Zapier uses this configuration for creating objects in bulk.\",\n \"type\": \"object\",\n \"required\": [\n \"groupedBy\",\n \"limit\"\n ],\n \"properties\": {\n \"groupedBy\": {\n \"description\": \"The list of keys of input fields to group bulk-create with. The actual user data provided for the fields will be used during execution. Note that a required input field should be referenced to get user data always.\",\n \"type\": \"array\",\n \"minItems\": 1\n },\n \"limit\": {\n \"description\": \"The maximum number of items to call `performBuffer` with. **Note** that it is capped by the platform to prevent exceeding the [AWS Lambda's request/response payload size quota of 6 MB](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html#function-configuration-deployment-and-execution). Also, the execution is time-bound; we recommend reducing it upon consistent timeout.\",\n \"type\": \"integer\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "BufferConfigSchema required=[groupedBy, limit]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/BufferConfigSchema", "required": ["groupedBy", "limit"], "properties": ["groupedBy", "limit"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:basiccreateoperationschema", "kind": "schema_type", "key": "BasicCreateOperationSchema", "title": "BasicCreateOperationSchema", "summary": "Represents the fundamental mechanics of a create.", "body": "# `BasicCreateOperationSchema`\n\n> Represents the fundamental mechanics of a create.\n\n## High-level description\n\nRepresents the fundamental mechanics of a create.\n\n## Internals\n\nJSON Schema id `/BasicCreateOperationSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n resource?: /KeySchema; // Optionally reference and extends a resource. Allows Zapier to automatically tie together samples, lists and hooks, great\n perform?: any; // How will Zapier get the data? This can be a function like `(z) => [{id: 123}]` or a request like `{url: 'http...'}`. Exa\n performResume?: /FunctionSchema; // A function that parses data from a perform (which uses z.generateCallbackUrl()) and callback request to resume this acti\n performGet?: any; // How will Zapier get a single record? If you find yourself reaching for this - consider resources and their built-in get \n inputFields?: /InputFieldsSchema; // What should the form a user sees and configures look like?\n inputFieldGroups?: /InputFieldGroupsSchema; // Defines groups for organizing input fields in the UI. Each group can have a key, label, and emphasis styling.\n outputFields?: /OutputFieldsSchema; // What fields of data will this return? Will use resource outputFields if missing, will also use sample if available.\n sample?: object; // What does a sample of data look like? Will use resource sample if missing. Requirement waived if `display.hidden` is tru\n lock?: /LockObjectSchema; // Zapier uses this configuration to ensure this action is performed one at a time per scope (avoid concurrency).\n throttle?: /ThrottleObjectSchema; // Zapier uses this configuration to apply throttling when the limit for the window is exceeded.\n cleanInputData?: boolean; // If true, Zapier removes empty strings, `null`, `undefined`, and empty Arrays or objects from `bundle.inputData` recursiv\n buffer?: /BufferConfigSchema; // Currently an **internal-only** feature. Zapier uses this configuration for creating objects in bulk with `performBuffer`\n performBuffer?: /FunctionSchema; // Currently an **internal-only** feature. A function to create objects in bulk with. `buffer` and `performBuffer` must eit\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/BasicCreateOperationSchema\",\n \"description\": \"Represents the fundamental mechanics of a create.\",\n \"type\": \"object\",\n \"properties\": {\n \"resource\": {\n \"description\": \"Optionally reference and extends a resource. Allows Zapier to automatically tie together samples, lists and hooks, greatly improving the UX. EG: if you had another trigger reusing a resource but filtering the results.\",\n \"$ref\": \"/KeySchema\"\n },\n \"perform\": {\n \"description\": \"How will Zapier get the data? This can be a function like `(z) => [{id: 123}]` or a request like `{url: 'http...'}`. Exactly one of `perform` or `performBuffer` must be defined. If you choose to define `buffer` and `performBuffer`, you must omit `perform`.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ],\n \"docAnnotation\": {\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"no (with exceptions, see description)\"\n }\n }\n },\n \"performResume\": {\n \"description\": \"A function that parses data from a perform (which uses z.generateCallbackUrl()) and callback request to resume this action.\",\n \"$ref\": \"/FunctionSchema\"\n },\n \"performGet\": {\n \"description\": \"How will Zapier get a single record? If you find yourself reaching for this - consider resources and their built-in get methods.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"inputFields\": {\n \"description\": \"What should the form a user sees and configures look like?\",\n \"$ref\": \"/InputFieldsSchema\"\n },\n \"inputFieldGroups\": {\n \"description\": \"Defines groups for organizing input fields in the UI. Each group can have a key, label, and emphasis styling.\",\n \"$ref\": \"/InputFieldGroupsSchema\"\n },\n \"outputFields\": {\n \"description\": \"What fields of data will this return? Will use resource outputFields if missing, will also use sample if available.\",\n \"$ref\": \"/OutputFieldsSchema\"\n },\n \"sample\": {\n \"description\": \"What does a sample of data look like? Will use resource sample if missing. Requirement waived if `display.hidden` is true or if this belongs to a resource that has a top-level sample\",\n \"type\": \"object\",\n \"minProperties\": 1,\n \"docAnnotation\": {\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"**yes** (with exceptions, see description)\"\n }\n }\n },\n \"lock\": {\n \"description\": \"Zapier uses this configuration to ensure this action is performed one at a time per scope (avoid concurrency).\",\n \"$ref\": \"/LockObjectSchema\"\n },\n \"throttle\": {\n \"description\": \"Zapier uses this configuration to apply throttling when the limit for the window is exceeded.\",\n \"$ref\": \"/ThrottleObjectSchema\"\n },\n \"cleanInputData\": {\n \"description\": \"If true, Zapier removes empty strings, `null`, `undefined`, and empty Arrays or objects from `bundle.inputData` recursively before passing it to your `perform*` function. If you want to handle empty values yourself in your code, explicitly set this to false. There is also a global flag with the same name in `App.flags`. This one takes precedence over the global one.\",\n \"type\": \"boolean\"\n },\n \"buffer\": {\n \"description\": \"Currently an **internal-only** feature. Zapier uses this configuration for creating objects in bulk with `performBuffer`.\",\n \"$ref\": \"/BufferConfigSchema\",\n \"docAnnotation\": {\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"no (with exceptions, see description)\"\n }\n }\n },\n \"performBuffer\": {\n \"description\": \"Currently an **internal-only** feature. A function to create objects in bulk with. `buffer` and `performBuffer` must either both be defined or neither. Additionally, only one of `perform` or `performBuffer` can be defined. If you choose to define `perform`, you must omit `buffer` and `performBuffer`.\",\n \"$ref\": \"/FunctionSchema\",\n \"docAnnotation\": {\n \"required\": {\n \"type\": \"replace\",\n \"value\": \"no (with exceptions, see description)\"\n }\n }\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "BasicCreateOperationSchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/BasicCreateOperationSchema", "required": [], "properties": ["resource", "perform", "performResume", "performGet", "inputFields", "inputFieldGroups", "outputFields", "sample", "lock", "throttle", "cleanInputData", "buffer", "performBuffer"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:createschema", "kind": "schema_type", "key": "CreateSchema", "title": "CreateSchema", "summary": "How will Zapier create a new object?", "body": "# `CreateSchema`\n\n> How will Zapier create a new object?\n\n## High-level description\n\nHow will Zapier create a new object?\n\n## Internals\n\nJSON Schema id `/CreateSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: key, noun, display, operation\n key: /KeySchema; // A key to uniquely identify this create.\n noun: string; // A noun for this create that completes the sentence \"creates a new XXX\".\n display: /BasicDisplaySchema; // Configures the UI for this create.\n operation: /BasicCreateOperationSchema; // Powers the functionality for this create.\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/CreateSchema\",\n \"description\": \"How will Zapier create a new object?\",\n \"type\": \"object\",\n \"required\": [\n \"key\",\n \"noun\",\n \"display\",\n \"operation\"\n ],\n \"properties\": {\n \"key\": {\n \"description\": \"A key to uniquely identify this create.\",\n \"$ref\": \"/KeySchema\"\n },\n \"noun\": {\n \"description\": \"A noun for this create that completes the sentence \\\"creates a new XXX\\\".\",\n \"type\": \"string\",\n \"minLength\": 2,\n \"maxLength\": 255\n },\n \"display\": {\n \"description\": \"Configures the UI for this create.\",\n \"$ref\": \"/BasicDisplaySchema\"\n },\n \"operation\": {\n \"description\": \"Powers the functionality for this create.\",\n \"$ref\": \"/BasicCreateOperationSchema\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "CreateSchema required=[key, noun, display, operation]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/CreateSchema", "required": ["key", "noun", "display", "operation"], "properties": ["key", "noun", "display", "operation"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:searchorcreateschema", "kind": "schema_type", "key": "SearchOrCreateSchema", "title": "SearchOrCreateSchema", "summary": "Pair an existing search and a create to enable \"Find or Create\" functionality in your app", "body": "# `SearchOrCreateSchema`\n\n> Pair an existing search and a create to enable \"Find or Create\" functionality in your app\n\n## High-level description\n\nPair an existing search and a create to enable \"Find or Create\" functionality in your app\n\n## Internals\n\nJSON Schema id `/SearchOrCreateSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: key, display, search, create\n key: /KeySchema; // A key to uniquely identify this search-or-create. Must match the search key.\n display: /BasicDisplaySchema; // Configures the UI for this search-or-create.\n search: /KeySchema; // The key of the search that powers this search-or-create\n create: /KeySchema; // The key of the create that powers this search-or-create\n update?: /KeySchema; // EXPERIMENTAL: The key of the update action (in `creates`) that will be used if a search succeeds.\n updateInputFromSearchOutput?: /FlatObjectSchema; // EXPERIMENTAL: A mapping where the key represents the input field for the update action, and the value represents the fie\n searchUniqueInputToOutputConstraint?: object; // EXPERIMENTAL: A mapping where the key represents an input field for the search action, and the value represents how that\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/SearchOrCreateSchema\",\n \"description\": \"Pair an existing search and a create to enable \\\"Find or Create\\\" functionality in your app\",\n \"type\": \"object\",\n \"required\": [\n \"key\",\n \"display\",\n \"search\",\n \"create\"\n ],\n \"properties\": {\n \"key\": {\n \"description\": \"A key to uniquely identify this search-or-create. Must match the search key.\",\n \"$ref\": \"/KeySchema\"\n },\n \"display\": {\n \"description\": \"Configures the UI for this search-or-create.\",\n \"$ref\": \"/BasicDisplaySchema\"\n },\n \"search\": {\n \"description\": \"The key of the search that powers this search-or-create\",\n \"$ref\": \"/KeySchema\"\n },\n \"create\": {\n \"description\": \"The key of the create that powers this search-or-create\",\n \"$ref\": \"/KeySchema\"\n },\n \"update\": {\n \"description\": \"EXPERIMENTAL: The key of the update action (in `creates`) that will be used if a search succeeds.\",\n \"$ref\": \"/KeySchema\"\n },\n \"updateInputFromSearchOutput\": {\n \"description\": \"EXPERIMENTAL: A mapping where the key represents the input field for the update action, and the value represents the field from the search action's output that should be mapped to the update action's input field.\",\n \"$ref\": \"/FlatObjectSchema\"\n },\n \"searchUniqueInputToOutputConstraint\": {\n \"description\": \"EXPERIMENTAL: A mapping where the key represents an input field for the search action, and the value represents how that field's value will be used to filter down the search output for an exact match.\",\n \"type\": \"object\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "SearchOrCreateSchema required=[key, display, search, create]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/SearchOrCreateSchema", "required": ["key", "display", "search", "create"], "properties": ["key", "display", "search", "create", "update", "updateInputFromSearchOutput", "searchUniqueInputToOutputConstraint"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:searchorcreatesschema", "kind": "schema_type", "key": "SearchOrCreatesSchema", "title": "SearchOrCreatesSchema", "summary": "Enumerates the search-or-creates your app has available for users.", "body": "# `SearchOrCreatesSchema`\n\n> Enumerates the search-or-creates your app has available for users.\n\n## High-level description\n\nEnumerates the search-or-creates your app has available for users.\n\n## Internals\n\nJSON Schema id `/SearchOrCreatesSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/SearchOrCreatesSchema\",\n \"description\": \"Enumerates the search-or-creates your app has available for users.\",\n \"type\": \"object\",\n \"patternProperties\": {\n \"^[a-zA-Z]+[a-zA-Z0-9_]*$\": {\n \"description\": \"Any unique key can be used and its values will be validated against the SearchOrCreateSchema.\",\n \"$ref\": \"/SearchOrCreateSchema\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "SearchOrCreatesSchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/SearchOrCreatesSchema", "required": [], "properties": [], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:authenticationschema", "kind": "schema_type", "key": "AuthenticationSchema", "title": "AuthenticationSchema", "summary": "Represents authentication schemes.", "body": "# `AuthenticationSchema`\n\n> Represents authentication schemes.\n\n## High-level description\n\nRepresents authentication schemes.\n\n## Internals\n\nJSON Schema id `/AuthenticationSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: type, test\n type: string; // Choose which scheme you want to use.\n test: any; // A function or request that confirms the authentication is working.\n fields?: /AuthFieldsSchema; // Fields you can request from the user before they connect your app to Zapier.\n connectionLabel?: any; // A string with variables, function, or request that returns the connection label for the authenticated user.\n basicConfig?: /AuthenticationBasicConfigSchema; // \n customConfig?: /AuthenticationCustomConfigSchema; // \n digestConfig?: /AuthenticationDigestConfigSchema; // \n oauth1Config?: /AuthenticationOAuth1ConfigSchema; // \n oauth2Config?: /AuthenticationOAuth2ConfigSchema; // \n sessionConfig?: /AuthenticationSessionConfigSchema; // \n```\n\n## Schema\n\n```json\n{\n \"id\": \"/AuthenticationSchema\",\n \"description\": \"Represents authentication schemes.\",\n \"type\": \"object\",\n \"required\": [\n \"type\",\n \"test\"\n ],\n \"properties\": {\n \"type\": {\n \"description\": \"Choose which scheme you want to use.\",\n \"type\": \"string\",\n \"enum\": [\n \"basic\",\n \"custom\",\n \"digest\",\n \"oauth1\",\n \"oauth2\",\n \"session\"\n ]\n },\n \"test\": {\n \"description\": \"A function or request that confirms the authentication is working.\",\n \"oneOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ]\n },\n \"fields\": {\n \"description\": \"Fields you can request from the user before they connect your app to Zapier.\",\n \"$ref\": \"/AuthFieldsSchema\"\n },\n \"connectionLabel\": {\n \"description\": \"A string with variables, function, or request that returns the connection label for the authenticated user.\",\n \"anyOf\": [\n {\n \"$ref\": \"/RequestSchema\"\n },\n {\n \"$ref\": \"/FunctionSchema\"\n },\n {\n \"type\": \"string\"\n }\n ]\n },\n \"basicConfig\": {\n \"$ref\": \"/AuthenticationBasicConfigSchema\"\n },\n \"customConfig\": {\n \"$ref\": \"/AuthenticationCustomConfigSchema\"\n },\n \"digestConfig\": {\n \"$ref\": \"/AuthenticationDigestConfigSchema\"\n },\n \"oauth1Config\": {\n \"$ref\": \"/AuthenticationOAuth1ConfigSchema\"\n },\n \"oauth2Config\": {\n \"$ref\": \"/AuthenticationOAuth2ConfigSchema\"\n },\n \"sessionConfig\": {\n \"$ref\": \"/AuthenticationSessionConfigSchema\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "AuthenticationSchema required=[type, test]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/AuthenticationSchema", "required": ["type", "test"], "properties": ["type", "test", "fields", "connectionLabel", "basicConfig", "customConfig", "digestConfig", "oauth1Config", "oauth2Config", "sessionConfig"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:resourcesschema", "kind": "schema_type", "key": "ResourcesSchema", "title": "ResourcesSchema", "summary": "All the resources that underlie common CRUD methods powering automatically handled triggers, creates, and searches for your app. Zapier will break these apart for you.", "body": "# `ResourcesSchema`\n\n> All the resources that underlie common CRUD methods powering automatically handled triggers, creates, and searches for your app. Zapier will break these apart for you.\n\n## High-level description\n\nAll the resources that underlie common CRUD methods powering automatically handled triggers, creates, and searches for your app. Zapier will break these apart for you.\n\n## Internals\n\nJSON Schema id `/ResourcesSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/ResourcesSchema\",\n \"description\": \"All the resources that underlie common CRUD methods powering automatically handled triggers, creates, and searches for your app. Zapier will break these apart for you.\",\n \"type\": \"object\",\n \"patternProperties\": {\n \"^[a-zA-Z]+[a-zA-Z0-9_]*$\": {\n \"description\": \"Any unique key can be used and its values will be validated against the ResourceSchema.\",\n \"$ref\": \"/ResourceSchema\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "ResourcesSchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/ResourcesSchema", "required": [], "properties": [], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:bulkreadsschema", "kind": "schema_type", "key": "BulkReadsSchema", "title": "BulkReadsSchema", "summary": "Enumerates the bulk reads your app exposes.", "body": "# `BulkReadsSchema`\n\n> Enumerates the bulk reads your app exposes.\n\n## High-level description\n\nEnumerates the bulk reads your app exposes.\n\n## Internals\n\nJSON Schema id `/BulkReadsSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/BulkReadsSchema\",\n \"description\": \"Enumerates the bulk reads your app exposes.\",\n \"type\": \"object\",\n \"patternProperties\": {\n \"^[a-zA-Z]+[a-zA-Z0-9_]*$\": {\n \"description\": \"Any unique key can be used and its values will be validated against the BulkReadSchema.\",\n \"$ref\": \"/BulkReadSchema\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "BulkReadsSchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/BulkReadsSchema", "required": [], "properties": [], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:triggersschema", "kind": "schema_type", "key": "TriggersSchema", "title": "TriggersSchema", "summary": "Enumerates the triggers your app has available for users.", "body": "# `TriggersSchema`\n\n> Enumerates the triggers your app has available for users.\n\n## High-level description\n\nEnumerates the triggers your app has available for users.\n\n## Internals\n\nJSON Schema id `/TriggersSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/TriggersSchema\",\n \"description\": \"Enumerates the triggers your app has available for users.\",\n \"type\": \"object\",\n \"patternProperties\": {\n \"^[a-zA-Z]+[a-zA-Z0-9_]*$\": {\n \"description\": \"Any unique key can be used and its values will be validated against the TriggerSchema.\",\n \"$ref\": \"/TriggerSchema\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "TriggersSchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/TriggersSchema", "required": [], "properties": [], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:searchesschema", "kind": "schema_type", "key": "SearchesSchema", "title": "SearchesSchema", "summary": "Enumerates the searches your app has available for users.", "body": "# `SearchesSchema`\n\n> Enumerates the searches your app has available for users.\n\n## High-level description\n\nEnumerates the searches your app has available for users.\n\n## Internals\n\nJSON Schema id `/SearchesSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/SearchesSchema\",\n \"description\": \"Enumerates the searches your app has available for users.\",\n \"type\": \"object\",\n \"patternProperties\": {\n \"^[a-zA-Z]+[a-zA-Z0-9_]*$\": {\n \"description\": \"Any unique key can be used and its values will be validated against the SearchSchema.\",\n \"$ref\": \"/SearchSchema\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "SearchesSchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/SearchesSchema", "required": [], "properties": [], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:createsschema", "kind": "schema_type", "key": "CreatesSchema", "title": "CreatesSchema", "summary": "Enumerates the creates your app has available for users.", "body": "# `CreatesSchema`\n\n> Enumerates the creates your app has available for users.\n\n## High-level description\n\nEnumerates the creates your app has available for users.\n\n## Internals\n\nJSON Schema id `/CreatesSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/CreatesSchema\",\n \"description\": \"Enumerates the creates your app has available for users.\",\n \"type\": \"object\",\n \"patternProperties\": {\n \"^[a-zA-Z]+[a-zA-Z0-9_]*$\": {\n \"description\": \"Any unique key can be used and its values will be validated against the CreateSchema.\",\n \"$ref\": \"/CreateSchema\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "CreatesSchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/CreatesSchema", "required": [], "properties": [], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:searchandcreatesschema", "kind": "schema_type", "key": "SearchAndCreatesSchema", "title": "SearchAndCreatesSchema", "summary": "Alias for /SearchOrCreatesSchema", "body": "# `SearchAndCreatesSchema`\n\n> Alias for /SearchOrCreatesSchema\n\n## High-level description\n\nAlias for /SearchOrCreatesSchema\n\n## Internals\n\nJSON Schema id `/SearchAndCreatesSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/SearchAndCreatesSchema\",\n \"description\": \"Alias for /SearchOrCreatesSchema\",\n \"type\": \"object\",\n \"patternProperties\": {\n \"^[a-zA-Z]+[a-zA-Z0-9_]*$\": {\n \"description\": \"Any unique key can be used and its values will be validated against the SearchOrCreateSchema.\",\n \"$ref\": \"/SearchOrCreateSchema\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "SearchAndCreatesSchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/SearchAndCreatesSchema", "required": [], "properties": [], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:versionschema", "kind": "schema_type", "key": "VersionSchema", "title": "VersionSchema", "summary": "Represents a simplified semver string, from `0.0.0` to `999.999.999` with optional simplified label. They need to be case-insensitive unique.", "body": "# `VersionSchema`\n\n> Represents a simplified semver string, from `0.0.0` to `999.999.999` with optional simplified label. They need to be case-insensitive unique.\n\n## High-level description\n\nRepresents a simplified semver string, from `0.0.0` to `999.999.999` with optional simplified label. They need to be case-insensitive unique.\n\n## Internals\n\nJSON Schema id `/VersionSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/VersionSchema\",\n \"description\": \"Represents a simplified semver string, from `0.0.0` to `999.999.999` with optional simplified label. They need to be case-insensitive unique.\",\n \"type\": \"string\",\n \"pattern\": \"^(?:0|[1-9]\\\\d{0,2})\\\\.(?:0|[1-9]\\\\d{0,2})\\\\.(?:0|[1-9]\\\\d{0,2})(?:-(?=.{1,12}$)[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*)?$\",\n \"minLength\": 5,\n \"maxLength\": 24\n}\n```", "usage": "", "signature": "VersionSchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/VersionSchema", "required": [], "properties": [], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:middlewaresschema", "kind": "schema_type", "key": "MiddlewaresSchema", "title": "MiddlewaresSchema", "summary": "List of before or after middlewares. Can be an array of functions or a single function", "body": "# `MiddlewaresSchema`\n\n> List of before or after middlewares. Can be an array of functions or a single function\n\n## High-level description\n\nList of before or after middlewares. Can be an array of functions or a single function\n\n## Internals\n\nJSON Schema id `/MiddlewaresSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/MiddlewaresSchema\",\n \"description\": \"List of before or after middlewares. Can be an array of functions or a single function\",\n \"oneOf\": [\n {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"/FunctionSchema\"\n }\n },\n {\n \"$ref\": \"/FunctionSchema\"\n }\n ],\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "MiddlewaresSchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/MiddlewaresSchema", "required": [], "properties": [], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:hydratorsschema", "kind": "schema_type", "key": "HydratorsSchema", "title": "HydratorsSchema", "summary": "A bank of named functions that you can use in `z.hydrate('someName')` to lazily load data.", "body": "# `HydratorsSchema`\n\n> A bank of named functions that you can use in `z.hydrate('someName')` to lazily load data.\n\n## High-level description\n\nA bank of named functions that you can use in `z.hydrate('someName')` to lazily load data.\n\n## Internals\n\nJSON Schema id `/HydratorsSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/HydratorsSchema\",\n \"description\": \"A bank of named functions that you can use in `z.hydrate('someName')` to lazily load data.\",\n \"type\": \"object\",\n \"patternProperties\": {\n \"^[a-zA-Z]+[a-zA-Z0-9]*$\": {\n \"description\": \"Any unique key can be used in `z.hydrate('uniqueKeyHere')`.\",\n \"$ref\": \"/FunctionSchema\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "HydratorsSchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/HydratorsSchema", "required": [], "properties": [], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_type:appflagsschema", "kind": "schema_type", "key": "AppFlagsSchema", "title": "AppFlagsSchema", "summary": "Codifies high-level options for your integration.", "body": "# `AppFlagsSchema`\n\n> Codifies high-level options for your integration.\n\n## High-level description\n\nCodifies high-level options for your integration.\n\n## Internals\n\nJSON Schema id `/AppFlagsSchema` from zapier-platform-schema 19.1.0. Used by `zapier-platform validate` / build.\n\n## Typed inputs (properties)\n\n```ts\n// required: —\n skipHttpPatch?: boolean; // By default, Zapier patches the core `http` module so that all requests (including those from 3rd-party SDKs) can be logg\n skipThrowForStatus?: boolean; // Starting in `core` version `10.0.0`, `response.throwForStatus()` was called by default. We introduced a per-request way \n throwForThrottlingEarly?: boolean; // Starting in `core` version `18.0.0`, 429 (throttling) responses throw a `ThrottledError` before `afterResponse` middlewa\n cleanInputData?: boolean; // If true, Zapier removes empty strings, `null`, `undefined`, and empty Arrays or objects from `bundle.inputData` recursiv\n```\n\n## Schema\n\n```json\n{\n \"id\": \"/AppFlagsSchema\",\n \"description\": \"Codifies high-level options for your integration.\",\n \"type\": \"object\",\n \"properties\": {\n \"skipHttpPatch\": {\n \"description\": \"By default, Zapier patches the core `http` module so that all requests (including those from 3rd-party SDKs) can be logged. Set this to true if you're seeing issues using an SDK (such as AWS).\",\n \"type\": \"boolean\"\n },\n \"skipThrowForStatus\": {\n \"description\": \"Starting in `core` version `10.0.0`, `response.throwForStatus()` was called by default. We introduced a per-request way to opt-out of this behavior. This flag takes that a step further and controls that behavior integration-wide **for requests made using `z.request()`**. Unless they specify otherwise (per-request, or via middleware), [Shorthand requests](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#shorthand-http-requests) _always_ call `throwForStatus()`. `z.request()` calls can also ignore this flag if they set `skipThrowForStatus` directly. It is important to note that for oauth2 or session auths with `authRefresh:true`, `401` status codes will throw a `RefreshAuthError` regardless of `skipThrowForStatus`, and will need to be handled manually if intervention is required.\",\n \"type\": \"boolean\"\n },\n \"throwForThrottlingEarly\": {\n \"description\": \"Starting in `core` version `18.0.0`, 429 (throttling) responses throw a `ThrottledError` before `afterResponse` middleware runs by default. Set this flag to `true` to preserve the old behavior where `afterResponse` middleware can see and handle 429 responses. This flag can be overridden per-request by setting `throwForThrottlingEarly` directly on the request options.\",\n \"type\": \"boolean\"\n },\n \"cleanInputData\": {\n \"description\": \"If true, Zapier removes empty strings, `null`, `undefined`, and empty Arrays or objects from `bundle.inputData` recursively before passing it to your `perform*` function. If you want to handle empty values yourself in your code, explicitly set this to false. This is a global flag that affects all the triggers and actions in your integration. The `cleanInputData` flag in `operation` takes precedence over this one.\",\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n}\n```", "usage": "", "signature": "AppFlagsSchema required=[]", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/blob/main/packages/schema/exported-schema.json", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/exported-schema.json", "section": "schema", "tags": ["json", "schema"], "related": [], "meta": {"id": "/AppFlagsSchema", "required": [], "properties": ["skipHttpPatch", "skipThrowForStatus", "throwForThrottlingEarly", "cleanInputData"], "version": "19.1.0"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "schema_json:example-definition", "kind": "schema_json", "key": "example-definition", "title": "Minimal valid App definition.json", "summary": "Official example App JSON used by schema tests.", "body": "{\n \"version\": \"1.2.30\",\n \"platformVersion\": \"1.2.30\",\n \"beforeRequest\": \"$func$2$f$\",\n \"afterResponse\": [\"$func$2$f$\"],\n \"requestTemplate\": {\n \"headers\": {\n \"X-MyCustomHeader\": \"my header value\"\n }\n },\n \"authentication\": {\n \"type\": \"oauth2\",\n \"test\": {\n \"url\": \"https://fake-crm.getsandbox.com/ping\",\n \"method\": \"GET\"\n },\n \"fields\": [\n {\n \"key\": \"access_token\",\n \"computed\": true\n },\n {\n \"key\": \"refresh_token\",\n \"computed\": true\n }\n ],\n \"oauth2Config\": {\n \"authorizeUrl\": \"$func$2$f$\",\n \"getAccessToken\": {\n \"url\": \"https://fake-crm.getsandbox.com/oauth/access_token\",\n \"method\": \"POST\"\n },\n \"scope\": \"tags,users,contacts\",\n \"autoRefresh\": false,\n \"enablePkce\": false\n },\n \"connectionLabel\": \"{{inputData.email}}\"\n },\n \"resources\": {\n \"tag\": {\n \"key\": \"tag\",\n \"noun\": \"Tag\",\n \"sample\": {\n \"id\": 1,\n \"name\": \"test tag\"\n },\n \"get\": {\n \"display\": {\n \"label\": \"Get Tag by ID\",\n \"description\": \"Grab a specific Tag by ID.\"\n },\n \"operation\": {\n \"perform\": {\n \"url\": \"https://fake-crm.getsandbox.com/tags/{{inputData.id}}\"\n },\n \"sample\": {\n \"id\": 385,\n \"name\": \"proactive enable ROI\"\n },\n \"inputFields\": [\n {\n \"key\": \"id\",\n \"required\": true\n }\n ]\n }\n },\n \"list\": {\n \"display\": {\n \"label\": \"New Tag\",\n \"description\": \"Trigger when a new Tag is created in your account.\"\n },\n \"operation\": {\n \"perform\": {\n \"url\": \"https://fake-crm.getsandbox.com/tags\"\n },\n \"sample\": {\n \"id\": 385,\n \"name\": \"proactive enable ROI\"\n }\n }\n },\n \"create\": {\n \"display\": {\n \"label\": \"Create Tag\",\n \"description\": \"Create a new Tag in your account.\"\n },\n \"operation\": {\n \"perform\": \"$func$2$f$\",\n \"sample\": {\n \"id\": 1,\n \"name\": \"proactive enable ROI\"\n }\n }\n }\n },\n \"user\": {\n \"key\": \"user\",\n \"noun\": \"User\",\n \"sample\": {\n \"id\": 1,\n \"name\": \"Test McTesterson\",\n \"email\": \"test@mctesterson.com\"\n },\n \"get\": {\n \"display\": {\n \"label\": \"Get User by ID\",\n \"description\": \"Grab a specific User by ID.\"\n },\n \"operation\": {\n \"perform\": {\n \"url\": \"https://fake-crm.getsandbox.com/users/{{inputData.id}}\"\n },\n \"sample\": {\n \"id\": 1,\n \"name\": \"Jalen Bode\",\n \"email\": \"jalen.bode@company.com\"\n },\n \"inputFields\": [\n {\n \"key\": \"id\",\n \"required\": true\n }\n ]\n }\n },\n \"list\": {\n \"display\": {\n \"label\": \"New User\",\n \"description\": \"Trigger when a new User is created in your account.\"\n },\n \"operation\": {\n \"perform\": {\n \"url\": \"https://fake-crm.getsandbox.com/users\"\n },\n \"sample\": {\n \"id\": 49,\n \"name\": \"Veronica Kuhn\",\n \"email\": \"veronica.kuhn@company.com\"\n }\n }\n }\n },\n \"contact\": {\n \"key\": \"contact\",\n \"noun\": \"Contact\",\n \"sample\": {\n \"id\": 1,\n \"name\": \"Test Contact\",\n \"company\": \"Test Inc\",\n \"email\": \"test@example.com.com\",\n \"phone\": \"1-111-555-7000\",\n \"address\": \"1234 Test Canyon\",\n \"owner_id\": 1,\n \"tag_ids\": [1, 2, 3]\n },\n \"get\": {\n \"display\": {\n \"label\": \"Get Contact by ID\",\n \"description\": \"Grab a specific Contact by ID.\"\n },\n \"operation\": {\n \"perform\": {\n \"url\": \"https://fake-crm.getsandbox.com/contacts/{{inputData.id}}\"\n },\n \"sample\": {\n \"id\": 1,\n \"name\": \"Rosalee Kub\",\n \"company\": \"Schmidt, O'Reilly and Moen\",\n \"email\": \"Rosalee_Kub47@hotmail.com\",\n \"phone\": \"412-916-6798 x3478\",\n \"address\": \"73375 Jacobson Turnpike\",\n \"owner_id\": 9,\n \"tag_ids\": [87]\n },\n \"inputFields\": [\n {\n \"key\": \"id\",\n \"required\": true\n }\n ]\n }\n },\n \"list\": {\n \"display\": {\n \"label\": \"New Contact\",\n \"description\": \"Trigger when a new Contact is created in your account.\"\n },\n \"operation\": {\n \"perform\": {\n \"url\": \"https://fake-crm.getsandbox.com/contacts\"\n },\n \"sample\": {\n \"id\": 1,\n \"name\": \"Rosalee Kub\",\n \"company\": \"Schmidt, O'Reilly and Moen\",\n \"email\": \"Rosalee_Kub47@hotmail.com\",\n \"phone\": \"412-916-6798 x3478\",\n \"address\": \"73375 Jacobson Turnpike\",\n \"owner_id\": 9,\n \"tag_ids\": [87]\n }\n }\n },\n \"create\": {\n \"display\": {\n \"label\": \"Create Contact\",\n \"description\": \"Create a new Contact in your account.\"\n },\n \"operation\": {\n \"perform\": \"$func$2$f$\",\n \"sample\": {\n \"id\": 1,\n \"name\": \"Rosalee Kub\",\n \"company\": \"Schmidt, O'Reilly and Moen\",\n \"email\": \"Rosalee_Kub47@hotmail.com\",\n \"phone\": \"412-916-6798 x3478\",\n \"address\": \"73375 Jacobson Turnpike\",\n \"owner_id\": 9,\n \"tag_ids\": [87]\n },\n \"inputFields\": [\n {\n \"key\": \"email\",\n \"label\": \"Email\",\n \"type\": \"string\",\n \"required\": true\n },\n {\n \"key\": \"name\",\n \"label\": \"Name\",\n \"type\": \"string\"\n },\n {\n \"key\": \"company\",\n \"label\": \"Company\",\n \"type\": \"string\"\n },\n {\n \"key\": \"phone\",\n \"label\": \"Phone\",\n \"type\": \"string\"\n },\n {\n \"key\": \"address\",\n \"label\": \"Address\",\n \"type\": \"text\"\n },\n {\n \"key\": \"owner_id\",\n \"label\": \"Owner\",\n \"type\": \"integer\",\n \"dynamic\": \"user.id\"\n },\n {\n \"key\": \"tag_id\",\n \"label\": \"Tag\",\n \"type\": \"integer\",\n \"dynamic\": \"tag.id.name\",\n \"search\": \"tag.id\"\n }\n ]\n }\n }\n }\n },\n \"triggers\": {\n \"contact_by_tag\": {\n \"key\": \"contact_by_tag\",\n \"noun\": \"Contact\",\n \"display\": {\n \"label\": \"New Tagged Contact\",\n \"description\": \"Trigger when a new Contact is tagged in your account.\"\n },\n \"operation\": {\n \"resource\": \"contact\",\n \"perform\": {\n \"url\": \"https://fake-crm.getsandbox.com/contacts?tag_id={{inputData.tagId}}\"\n },\n \"inputFields\": [\n {\n \"key\": \"tagId\",\n \"label\": \"Tag\",\n \"type\": \"integer\",\n \"dynamic\": \"tag.id\"\n }\n ],\n \"sample\": {\n \"id\": 1,\n \"name\": \"Test Contact\",\n \"company\": \"Test Inc\",\n \"email\": \"test@example.com.com\",\n \"phone\": \"1-111-555-7000\",\n \"address\": \"1234 Test Canyon\",\n \"owner_id\": 1,\n \"tag_ids\": [1, 2, 3]\n }\n }\n },\n \"tag_list\": {\n \"display\": {\n \"label\": \"New Tag\",\n \"description\": \"Trigger when a new Tag is created in your account.\"\n },\n \"operation\": {\n \"perform\": {\n \"url\": \"https://fake-crm.getsandbox.com/tags\"\n },\n \"sample\": {\n \"id\": 385,\n \"name\": \"proactive enable ROI\"\n },\n \"resource\": \"tag\",\n \"type\": \"polling\"\n },\n \"key\": \"tag_list\",\n \"noun\": \"Tag\"\n },\n \"user_list\": {\n \"display\": {\n \"label\": \"New User\",\n \"description\": \"Trigger when a new User is created in your account.\"\n },\n \"operation\": {\n \"perform\": {\n \"url\": \"https://fake-crm.getsandbox.com/users\"\n },\n \"sample\": {\n \"id\": 49,\n \"name\": \"Veronica Kuhn\",\n \"email\": \"veronica.kuhn@company.com\"\n },\n \"resource\": \"user\",\n \"type\": \"polling\"\n },\n \"key\": \"user_list\",\n \"noun\": \"User\"\n },\n \"contact_list\": {\n \"display\": {\n \"label\": \"New Contact\",\n \"description\": \"Trigger when a new Contact is created in your account.\"\n },\n \"operation\": {\n \"perform\": {\n \"url\": \"https://fake-crm.getsandbox.com/contacts\"\n },\n \"resource\": \"contact\",\n \"type\": \"polling\",\n \"sample\": {\n \"id\": 1,\n \"name\": \"Test Contact\",\n \"company\": \"Test Inc\",\n \"email\": \"test@example.com.com\",\n \"phone\": \"1-111-555-7000\",\n \"address\": \"1234 Test Canyon\",\n \"owner_id\": 1,\n \"tag_ids\": [1, 2, 3]\n }\n },\n \"key\": \"contact_list\",\n \"noun\": \"Contact\"\n }\n },\n \"searches\": {\n \"tag\": {\n \"display\": {\n \"label\": \"Find Tag\",\n \"description\": \"Finds a Tag.\"\n },\n \"operation\": {\n \"perform\": {\n \"url\": \"https://fake-crm.getsandbox.com/tags?name={{inputData.name}}\"\n },\n \"resource\": \"tag\",\n \"inputFields\": [\n {\n \"key\": \"name\",\n \"label\": \"Tag Name\",\n \"type\": \"string\"\n }\n ],\n \"sample\": {\n \"id\": 1,\n \"name\": \"test tag\"\n }\n },\n \"key\": \"tag\",\n \"noun\": \"Tag\"\n }\n },\n \"creates\": {\n \"tag_create\": {\n \"display\": {\n \"label\": \"Create Tag\",\n \"description\": \"Create a new Tag in your account.\"\n },\n \"operation\": {\n \"perform\": \"$func$2$f$\",\n \"resource\": \"tag\",\n \"sample\": {\n \"id\": 385,\n \"name\": \"proactive enable ROI\"\n }\n },\n \"key\": \"tag_create\",\n \"noun\": \"Tag\"\n },\n \"contact_create\": {\n \"display\": {\n \"label\": \"Create Contact\",\n \"description\": \"Create a new Contact in your account.\"\n },\n \"operation\": {\n \"perform\": \"$func$2$f$\",\n \"inputFields\": [\n {\n \"key\": \"email\",\n \"label\": \"Email\",\n \"type\": \"string\",\n \"required\": true\n },\n {\n \"key\": \"name\",\n \"label\": \"Name\",\n \"type\": \"string\"\n },\n {\n \"key\": \"company\",\n \"label\": \"Company\",\n \"type\": \"string\"\n },\n {\n \"key\": \"phone\",\n \"label\": \"Phone\",\n \"type\": \"string\"\n },\n {\n \"key\": \"address\",\n \"label\": \"Address\",\n \"type\": \"text\"\n },\n {\n \"key\": \"owner_id\",\n \"label\": \"Owner\",\n \"type\": \"integer\",\n \"dynamic\": \"user.id\"\n },\n {\n \"key\": \"tag_id\",\n \"label\": \"Tag\",\n \"type\": \"integer\",\n \"dynamic\": \"tag.id\"\n }\n ],\n \"resource\": \"contact\",\n \"sample\": {\n \"id\": 1,\n \"name\": \"Test Contact\",\n \"company\": \"Test Inc\",\n \"email\": \"test@example.com.com\",\n \"phone\": \"1-111-555-7000\",\n \"address\": \"1234 Test Canyon\",\n \"owner_id\": 1,\n \"tag_ids\": [1, 2, 3]\n }\n },\n \"key\": \"contact_create\",\n \"noun\": \"Contact\"\n }\n }\n}\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/packages/schema/examples/definition.json", "section": "schema", "tags": ["example", "schema"], "related": [], "meta": {}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "openapi:actions.yaml", "kind": "openapi", "key": "actions.yaml", "title": "Actions API (actions.yaml)", "summary": "Public access to Zapier Stored Actions and the runs that execute them — create, list, retrieve, update, and delete stored actions; trigger runs and fetch run results.", "body": "openapi: 3.1.0\ninfo:\n title: Actions API\n description: Public access to Zapier Stored Actions and the runs that execute them\n — create, list, retrieve, update, and delete stored actions; trigger runs and\n fetch run results.\n version: v1\n contact:\n url: https://docs.zapier.com\nservers:\n - url: https://api.zapier.com\n description: Production\ntags:\n - name: Stored Actions\n description: Operations related to a Stored Action\nsecurity:\n - OAuth: []\npaths:\n /actions/v1/stored-actions:\n get:\n operationId: listStoredActions\n description: 'Stored Actions endpoints handle the creation, execution, updates,\n and deletions\n\n of single created actions.'\n summary: List stored actions\n tags:\n - Stored Actions\n security:\n - OAuth:\n - external\n responses:\n '200':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/StoredActionRecordListResponse'\n examples:\n Success:\n value:\n results:\n - type: stored_action\n id: 01932123-02ea-01fc-3fbd-4d66d944064d\n connection_id: 019320ab-0000-7000-8000-abcdef012345\n selected_api: SplitwiseCLIAPI@1.0.0\n action_key: new_contact\n action_type: read\n inputs:\n first_name: John\n last_name: Doe\n meta:\n limit: 1\n offset: 0\n count: 1\n links:\n next: null\n description: 'Success: Includes all the Stored Actions for the caller. This\n could be an empty list.'\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n '400':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n BadRequest:\n value:\n errors:\n - status: 400\n code: bad_request\n title: Bad Request\n detail: Improperly formatted or incompleted request\n source: null\n meta: {}\n summary: Bad Request\n description: Indicates an error executing the request to list Stored Actions.\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n '403':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n PermissionDenied:\n value:\n errors:\n - status: 403\n code: permission_denied\n detail: User does not have enough permissions to perform action\n summary: Permission Denied\n description: Permission denied. Unauthorized request.\n '429':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n TooManyRequests:\n value:\n errors:\n - status: 429\n code: too_many_requests\n detail: Rate limit exceeded. Too many requests.\n summary: Too Many Requests\n description: Too many requests.\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n Retry-After:\n schema:\n type: integer\n description: Seconds to wait before retrying.\n required: true\n '500':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n UnhandledOrExternalServiceError:\n value:\n errors:\n - status: 500\n code: external_service_error\n detail: An error occurred with an external service.\n summary: Unhandled or External Service Error\n description: Internal Server Error\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n '503':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n ServiceUnavailableError:\n value:\n errors:\n - status: 503\n code: service_unavaiable\n detail: Service is temporarily unavailable\n summary: Service Unavailable Error\n description: Service Unavailable\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n Retry-After:\n schema:\n type: integer\n description: Seconds to wait before retrying.\n required: true\n post:\n operationId: createStoredAction\n description: 'Create Stored Action\n\n\n Creates a new stored action entry that can then be executed from a simpler\n call to\n\n /stored-actions with just the stored action `id`.\n\n\n This will not execute a StoredAction.\n\n\n This is an async process and will only respond with the id of the stored action\n and other meta data,\n\n and it is the callers responsibility to poll\n\n GET /stored-actions/{stored_action_id}/runs/{run_id} with the run id returned\n from\n\n POST /stored-actions/{stored_action_id}/run to fetch the results after executing\n a stored action.\n\n\n The triple (selected_api, action_type, action_key) is required to create a\n stored action.\n\n Only core actions are supported; external and custom (App Extension) actions\n cannot be\n\n created as stored actions via this endpoint.\n\n\n **Note on `connection_id`:** Other Zapier APIs may expose the same\n\n identifier under the field name `authentication_id`. The value is the\n\n same UUID — pass it here under the `connection_id` key.'\n summary: Create a stored action\n tags:\n - Stored Actions\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/StoredActionsCreateRequest'\n examples:\n ExamplePOSTRequest:\n value:\n data:\n connection_id: 019320ab-0000-7000-8000-abcdef012345\n selected_api: SplitwiseCLIAPI@1.0.0\n action_key: new_contact\n action_type: read\n inputs:\n first_name: John\n last_name: Doe\n summary: Example POST Request\n required: true\n security:\n - OAuth:\n - external\n responses:\n '200':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/StoredActionsCreateResponse'\n examples:\n Success:\n value:\n type: stored_action\n id: 123e4567-e89b-12d3-a456-426614174000\n description: A StoredAction record was successfully created.\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n '400':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n BadRequest:\n value:\n errors:\n - status: 400\n code: bad_request\n title: Bad Request\n detail: Improperly formatted or incompleted request\n source: null\n meta: {}\n summary: Bad Request\n description: Indicates an error creating a StoredAction record.\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n '403':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n PermissionDenied:\n value:\n errors:\n - status: 403\n code: permission_denied\n detail: User does not have enough permissions to perform action\n summary: Permission Denied\n description: Permission denied. Unauthorized request.\n '429':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n TooManyRequests:\n value:\n errors:\n - status: 429\n code: too_many_requests\n detail: Rate limit exceeded. Too many requests.\n summary: Too Many Requests\n description: Too many requests.\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n Retry-After:\n schema:\n type: integer\n description: Seconds to wait before retrying.\n required: true\n '500':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n UnhandledOrExternalServiceError:\n value:\n errors:\n - status: 500\n code: external_service_error\n detail: An error occurred with an external service.\n summary: Unhandled or External Service Error\n description: Internal Server Error\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n '503':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n ServiceUnavailableError:\n value:\n errors:\n - status: 503\n code: service_unavaiable\n detail: Service is temporarily unavailable\n summary: Service Unavailable Error\n description: Service Unavailable\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n Retry-After:\n schema:\n type: integer\n description: Seconds to wait before retrying.\n required: true\n /actions/v1/stored-actions/{stored_action_id}:\n get:\n operationId: getStoredAction\n description: 'Stored Actions endpoints handle the creation, execution, updates,\n and deletions\n\n of single created actions.'\n summary: Get a stored action\n parameters:\n - in: path\n name: stored_action_id\n schema:\n type: string\n format: uuid\n required: true\n tags:\n - Stored Actions\n security:\n - OAuth:\n - external\n responses:\n '200':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/StoredActionRecord'\n examples:\n Success:\n value:\n type: stored_action\n id: 01932123-02ea-01fc-3fbd-4d66d944064d\n connection_id: 019320ab-0000-7000-8000-abcdef012345\n selected_api: SplitwiseCLIAPI@1.0.0\n action_key: new_contact\n action_type: read\n inputs:\n first_name: John\n last_name: Doe\n description: 'Success: Includes data for the requested Stored Action.'\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n '400':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n BadRequest:\n value:\n errors:\n - status: 400\n code: bad_request\n title: Bad Request\n detail: Improperly formatted or incompleted request\n source: null\n meta: {}\n summary: Bad Request\n description: Imporoperly formatted or incomplete request.\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n '404':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n Error:\n value:\n errors:\n - status: 404\n code: not_found\n title: Resource not found.\n detail: Here's a more readable explanation of what happened.\n source:\n pointer: /path/to/field\n meta: {}\n description: No results found for this Stored Action id.\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n '403':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n PermissionDenied:\n value:\n errors:\n - status: 403\n code: permission_denied\n detail: User does not have enough permissions to perform action\n summary: Permission Denied\n description: Permission denied. Unauthorized request.\n '429':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n TooManyRequests:\n value:\n errors:\n - status: 429\n code: too_many_requests\n detail: Rate limit exceeded. Too many requests.\n summary: Too Many Requests\n description: Too many requests.\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n Retry-After:\n schema:\n type: integer\n description: Seconds to wait before retrying.\n required: true\n '500':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n UnhandledOrExternalServiceError:\n value:\n errors:\n - status: 500\n code: external_service_error\n detail: An error occurred with an external service.\n summary: Unhandled or External Service Error\n description: Internal Server Error\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n '503':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n ServiceUnavailableError:\n value:\n errors:\n - status: 503\n code: service_unavaiable\n detail: Service is temporarily unavailable\n summary: Service Unavailable Error\n description: Service Unavailable\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n Retry-After:\n schema:\n type: integer\n description: Seconds to wait before retrying.\n required: true\n patch:\n operationId: updateStoredAction\n description: 'Stored Actions endpoints handle the creation, execution, updates,\n and deletions\n\n of single created actions.'\n summary: Update a stored action\n parameters:\n - in: path\n name: stored_action_id\n schema:\n type: string\n format: uuid\n required: true\n tags:\n - Stored Actions\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/PatchedStoredActionsUpdateRequest'\n examples:\n ExamplePATCHRequest:\n value:\n data:\n connection_id: 019320ab-0000-7000-8000-abcdef012345\n selected_api: SplitwiseCLIAPI@1.0.0\n action_key: new_contact\n action_type: read\n inputs:\n first_name: John\n last_name: Doe\n summary: Example PATCH Request\n security:\n - OAuth:\n - external\n responses:\n '200':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/StoredActionRecord'\n examples:\n Success:\n value:\n type: stored_action\n id: 01932123-02ea-01fc-3fbd-4d66d944064d\n connection_id: 019320ab-0000-7000-8000-abcdef012345\n selected_api: SplitwiseCLIAPI@1.0.0\n action_key: new_contact\n action_type: read\n inputs:\n first_name: John\n last_name: Doe\n description: A StoredAction record was successfully updated.\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n '400':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n BadRequest:\n value:\n errors:\n - status: 400\n code: bad_request\n title: Bad Request\n detail: Improperly formatted or incompleted request\n source: null\n meta: {}\n summary: Bad Request\n description: Indicates an error updating a StoredAction record.\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n '403':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n PermissionDenied:\n value:\n errors:\n - status: 403\n code: permission_denied\n detail: User does not have enough permissions to perform action\n summary: Permission Denied\n description: Permission denied. Unauthorized request.\n '429':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n TooManyRequests:\n value:\n errors:\n - status: 429\n code: too_many_requests\n detail: Rate limit exceeded. Too many requests.\n summary: Too Many Requests\n description: Too many requests.\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n Retry-After:\n schema:\n type: integer\n description: Seconds to wait before retrying.\n required: true\n '500':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n UnhandledOrExternalServiceError:\n value:\n errors:\n - status: 500\n code: external_service_error\n detail: An error occurred with an external service.\n summary: Unhandled or External Service Error\n description: Internal Server Error\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n '503':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n ServiceUnavailableError:\n value:\n errors:\n - status: 503\n code: service_unavaiable\n detail: Service is temporarily unavailable\n summary: Service Unavailable Error\n description: Service Unavailable\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n Retry-After:\n schema:\n type: integer\n description: Seconds to wait before retrying.\n required: true\n delete:\n operationId: deleteStoredAction\n description: 'Stored Actions endpoints handle the creation, execution, updates,\n and deletions\n\n of single created actions.'\n summary: Delete a stored action\n parameters:\n - in: path\n name: stored_action_id\n schema:\n type: string\n format: uuid\n required: true\n tags:\n - Stored Actions\n security:\n - OAuth:\n - external\n responses:\n '204':\n description: A StoredAction record was successfully deleted.\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n '400':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n BadRequest:\n value:\n errors:\n - status: 400\n code: bad_request\n title: Bad Request\n detail: Improperly formatted or incompleted request\n source: null\n meta: {}\n summary: Bad Request\n description: Indicates an error deleting a StoredAction record.\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n '403':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n PermissionDenied:\n value:\n errors:\n - status: 403\n code: permission_denied\n detail: User does not have enough permissions to perform action\n summary: Permission Denied\n description: Permission denied. Unauthorized request.\n '429':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n TooManyRequests:\n value:\n errors:\n - status: 429\n code: too_many_requests\n detail: Rate limit exceeded. Too many requests.\n summary: Too Many Requests\n description: Too many requests.\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n Retry-After:\n schema:\n type: integer\n description: Seconds to wait before retrying.\n required: true\n '500':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n UnhandledOrExternalServiceError:\n value:\n errors:\n - status: 500\n code: external_service_error\n detail: An error occurred with an external service.\n summary: Unhandled or External Service Error\n description: Internal Server Error\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n '503':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n ServiceUnavailableError:\n value:\n errors:\n - status: 503\n code: service_unavaiable\n detail: Service is temporarily unavailable\n summary: Service Unavailable Error\n description: Service Unavailable\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n Retry-After:\n schema:\n type: integer\n description: Seconds to wait before retrying.\n required: true\n /actions/v1/stored-actions/{stored_action_id}/run:\n post:\n operationId: createStoredActionRun\n description: \"Execute Stored Action\\n\\nExecutes an action on behalf of a user,\\\n \\ this is an async process.\\n\\nRequires the id from a stored action\\n\\nResponds\\\n \\ with the unique id for this run of the stored action. In order to fetch\\\n \\ results\\nyou will need to poll the GET /stored-actions/{stored_action_id}/runs/{run_id}\\\n \\ endpoint\\nwith that run id.\\n\\n**Billing**\\n\\nThe Actions API offers support\\\n \\ for directly billing users for Stored Action\\nRuns, and this functionality\\\n \\ is currently _opt-in_. To do this, you\\nmust provide a `billing` claim on\\\n \\ the JWT used to authenticate. This\\nclaim must be a JSON string, and any\\\n \\ values provided will override the\\ndefault configuration shown below. The\\\n \\ simplest approach is therefore\\nto set `is_billable` to true, and successful\\\n \\ Stored Action Runs will be\\ncharged to a user at a rate of one task.\\n\\n\\\n ```json\\nbilling: {\\n \\\"is_billable\\\": false,\\n \\\"origin\\\": \\\"actions_api\\\"\\\n ,\\n \\\"usage_type\\\": \\\"action_run\\\",\\n \\\"description\\\": \\\"an action was\\\n \\ run via Actions API\\\",\\n \\\"exemption_reason\\\": null,\\n \\\"exemption_details\\\"\\\n : null\\n}\\n```\\n\\n**Rate Limits**\\n\\nRate limiting is applied when Gargoyle\\\n \\ flag `edge_actions_api_rate_limiting_global`\\nis active. Requests are rate\\\n \\ limited by default unless the JWT explicitly sets\\n`rate_limit.exempt` to\\\n \\ true.\\n\\n```json\\nrate_limit: {\\n \\\"exempt\\\": true\\n}\\n```\\n\\nNon-exempted\\\n \\ requests are limited to 200 per 5 minutes by default. To set a custom\\n\\\n limit, include `limit_override` (11000 requests per 5 minutes):\\n\\n```json\\n\\\n rate_limit: {\\n \\\"exempt\\\": false,\\n \\\"limit_override\\\": 500\\n}\\n```\"\n summary: Run a stored action\n parameters:\n - in: path\n name: stored_action_id\n schema:\n type: string\n format: uuid\n required: true\n tags:\n - Stored Actions\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/StoredActionsRunRequest'\n examples:\n ExamplePOSTRequest:\n value:\n data:\n inputs:\n message: Hello World!\n page: '0'\n summary: Example POST Request\n required: true\n security:\n - OAuth:\n - external\n responses:\n '202':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/StoredActionsRunResponse'\n examples:\n Accepted:\n value:\n data:\n type: run\n id: 123e4567-e89b-12d3-a456-426614174000\n description: Acknowledges the request to execute a StoredAction\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n '400':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n BadRequest:\n value:\n errors:\n - status: 400\n code: bad_request\n title: Bad Request\n detail: Improperly formatted or incompleted request\n source: null\n meta: {}\n summary: Bad Request\n description: Indicates an error executing the request to run a StoredAction.\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n '403':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n PermissionDenied:\n value:\n errors:\n - status: 403\n code: permission_denied\n detail: User does not have enough permissions to perform action\n summary: Permission Denied\n description: Permission denied. Unauthorized request.\n '429':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n TooManyRequests:\n value:\n errors:\n - status: 429\n code: too_many_requests\n detail: Rate limit exceeded. Too many requests.\n summary: Too Many Requests\n description: Too many requests.\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n Retry-After:\n schema:\n type: integer\n description: Seconds to wait before retrying.\n required: true\n '500':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n UnhandledOrExternalServiceError:\n value:\n errors:\n - status: 500\n code: external_service_error\n detail: An error occurred with an external service.\n summary: Unhandled or External Service Error\n description: Internal Server Error\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n '503':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n ServiceUnavailableError:\n value:\n errors:\n - status: 503\n code: service_unavaiable\n detail: Service is temporarily unavailable\n summary: Service Unavailable Error\n description: Service Unavailable\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n Retry-After:\n schema:\n type: integer\n description: Seconds to wait before retrying.\n required: true\n '402':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n PaymentRequired:\n value:\n errors:\n - status: 402\n code: payment_required\n title: Payment Required\n detail: Insufficient tasks on account\n summary: Payment Required\n description: Payment Required - insufficient tasks on account\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n '424':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n PartnerAPITemporarilyUnavailable:\n value:\n errors:\n - status: 424\n code: partner_api_unhealthy\n title: Partner API Temporarily Unavailable\n detail: The app's API is currently unhealthy. Retry the request\n later.\n summary: Partner API Temporarily Unavailable\n description: Failed Dependency - the partner API is temporarily unhealthy\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 200. Maximum via limit_override: 1000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n /actions/v1/stored-actions/{stored_action_id}/runs/{run_id}:\n get:\n operationId: getStoredActionRun\n description: 'Fetch Stored Action Run\n\n\n Requires the id returned from a call to /stored-actions/{stored_action_id}/run\n\n to execute the stored action.\n\n\n The status code returned by this call does NOT denote the status of the action\n\n in an external system, but the status of the action processing from Zapier.\n\n\n Results are stored for seven days after the action was initially executed.'\n summary: Get stored action run results\n parameters:\n - in: path\n name: run_id\n schema:\n type: string\n format: uuid\n required: true\n - in: path\n name: stored_action_id\n schema:\n type: string\n format: uuid\n required: true\n tags:\n - Stored Actions\n security:\n - OAuth:\n - external\n responses:\n '200':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/StoredActionResult'\n examples:\n Success:\n value:\n type: run\n status: success\n results:\n - key: value\n next_page: '0'\n errors: []\n description: 'Success: Includes the results of the task run.'\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 600. Maximum via limit_override: 3000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n '202':\n description: The request is still processing, try fetching results again\n later.\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 600. Maximum via limit_override: 3000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n '400':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n BadRequest:\n value:\n errors:\n - status: 400\n code: bad_request\n title: Bad Request\n detail: Improperly formatted or incompleted request\n source: null\n meta: {}\n summary: Bad Request\n description: Imporoperly formatted or incomplete request.\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 600. Maximum via limit_override: 3000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n '404':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n Error:\n value:\n errors:\n - status: 404\n code: not_found\n title: Resource not found.\n detail: Here's a more readable explanation of what happened.\n source:\n pointer: /path/to/field\n meta: {}\n description: No results found for this run.\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 600. Maximum via limit_override: 3000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n '403':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n PermissionDenied:\n value:\n errors:\n - status: 403\n code: permission_denied\n detail: User does not have enough permissions to perform action\n summary: Permission Denied\n description: Permission denied. Unauthorized request.\n '429':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n TooManyRequests:\n value:\n errors:\n - status: 429\n code: too_many_requests\n detail: Rate limit exceeded. Too many requests.\n summary: Too Many Requests\n description: Too many requests.\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 600. Maximum via limit_override: 3000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n Retry-After:\n schema:\n type: integer\n description: Seconds to wait before retrying.\n required: true\n '500':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n UnhandledOrExternalServiceError:\n value:\n errors:\n - status: 500\n code: external_service_error\n detail: An error occurred with an external service.\n summary: Unhandled or External Service Error\n description: Internal Server Error\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 600. Maximum via limit_override: 3000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n '503':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionsErrorResponse'\n examples:\n ServiceUnavailableError:\n value:\n errors:\n - status: 503\n code: service_unavaiable\n detail: Service is temporarily unavailable\n summary: Service Unavailable Error\n description: Service Unavailable\n headers:\n X-RateLimit-Limit:\n schema:\n type: integer\n description: 'Effective request cap per 300-second window. Default:\n 600. Maximum via limit_override: 3000.'\n X-RateLimit-Remaining:\n schema:\n type: integer\n description: Requests remaining in the current window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: date-time\n description: Unix timestamp when the current 300-second window resets.\n Retry-After:\n schema:\n type: integer\n description: Seconds to wait before retrying.\n required: true\ncomponents:\n schemas:\n ActionTypeEnum:\n enum:\n - read\n - read_bulk\n - write\n - run\n - search\n - search_or_write\n - search_and_write\n - filter\n - tool\n type: string\n description: '* `read` - Read\n\n * `read_bulk` - Read Bulk\n\n * `write` - Write\n\n * `run` - Run\n\n * `search` - Search\n\n * `search_or_write` - Search Or Write\n\n * `search_and_write` - Search And Write\n\n * `filter` - Filter\n\n * `tool` - Tool'\n ActionsError:\n type: object\n description: Base Error definition\n properties:\n status:\n type: integer\n description: The HTTP status code applicable to this problem.\n code:\n type: string\n description: A unique identifier for this particular occurrence of the problem.\n title:\n type: string\n description: A short summary of the problem.\n detail:\n type: string\n description: A human-readable explanation specific to this occurrence of\n the problem.\n source:\n oneOf:\n - $ref: '#/components/schemas/ActionsErrorSource'\n - type: 'null'\n description: An object containing references to the primary source of the\n error.\n meta:\n type:\n - object\n - 'null'\n additionalProperties: {}\n description: Any additional metadata about the error.\n ActionsErrorResponse:\n type: object\n properties:\n errors:\n type: array\n items:\n $ref: '#/components/schemas/ActionsError'\n description: An array of error objects.\n required:\n - errors\n ActionsErrorSource:\n type: object\n description: Populates the `source` object inside our error responses.\n properties:\n pointer:\n type: string\n description: Pointer to the value in the request document that caused the\n error e.g. `/actions`.\n parameter:\n type: string\n description: A string indicating which URI query parameter caused the error.\n header:\n type: string\n description: A string indicating the name of a single request header which\n caused the error.\n ActionsFetchError:\n type: object\n description: The error information returned from a third party when running\n an action.\n properties:\n code:\n allOf:\n - $ref: '#/components/schemas/CodeEnum'\n description: 'Error type of the result object.\n\n\n * `user` - user\n\n * `authentication` - authentication\n\n * `partner` - partner\n\n * `system` - system\n\n * `throttled` - throttled\n\n * `system_throttled` - system_throttled\n\n * `hydration` - hydration\n\n * `authentication_access` - authentication_access'\n title:\n type: string\n description: A short summary of the problem.\n detail:\n type: string\n description: A human-readable explanation specific to this occurrence of\n the problem.\n delay:\n type: integer\n description: When a partner throttled the execution call (error_type = throttled),\n this value will hold the number of seconds to wait before retrying.\n meta:\n type:\n - object\n - 'null'\n additionalProperties: {}\n description: Any additional error information returned from the partner.\n CodeEnum:\n enum:\n - user\n - authentication\n - partner\n - system\n - throttled\n - system_throttled\n - hydration\n - authentication_access\n type: string\n description: '* `user` - user\n\n * `authentication` - authentication\n\n * `partner` - partner\n\n * `system` - system\n\n * `throttled` - throttled\n\n * `system_throttled` - system_throttled\n\n * `hydration` - hydration\n\n * `authentication_access` - authentication_access'\n PatchedStoredActionsUpdateRequest:\n type: object\n properties:\n data:\n $ref: '#/components/schemas/StoredActionUpdateRequestParams'\n StatusA45Enum:\n enum:\n - error\n - success\n - waiting\n type: string\n description: '* `error` - error\n\n * `success` - success\n\n * `waiting` - waiting'\n StoredActionRecord:\n type: object\n description: The shape of a payload representing a stored action record.\n properties:\n connection_id:\n type: string\n format: uuid\n description: UUID identifying the connection to use when executing a Stored\n Action.\n selected_api:\n type: string\n description: Something like `SlackAPI` (for Python apps) or `SplitwiseCLIAPI@1.0.0`\n (for CLI apps). Non-public apps are fine as long as the authed user can\n access them. If a version is included we attempt to use that version of\n the integration. If no version is provided we attempt to use the latest\n version of the integration\n action_key:\n type: string\n description: Name of the action in the integration. Such as `new_contact`.\n action_type:\n allOf:\n - $ref: '#/components/schemas/ActionTypeEnum'\n description: 'Specifies the type of action in the integration since some\n integrations could have similarly named actions with different actions\n types\n\n\n * `read` - Read\n\n * `read_bulk` - Read Bulk\n\n * `write` - Write\n\n * `run` - Run\n\n * `search` - Search\n\n * `search_or_write` - Search Or Write\n\n * `search_and_write` - Search And Write\n\n * `filter` - Filter\n\n * `tool` - Tool'\n inputs:\n default: {}\n description: 'Key/value pairs that the action needs to execute. In the example\n of SlackAPI this could be something like `{\"channel\": \"ABC\", \"text\": \"my\n message\"}`'\n id:\n type: string\n format: uuid\n description: The UUID id that identifies this stored action and can be used\n to execute the stored procedure by calling the POST /stored-actions/{stored_action_id}/run\n endpoint.\n type:\n type: string\n default: stored_action\n description: Specifies the resource type, as required by the JSON:API specification.\n required:\n - id\n StoredActionRecordListLinks:\n type: object\n description: Pagination navigation links for a Stored Action list response.\n properties:\n next:\n type:\n - string\n - 'null'\n format: uri\n description: Link to the next page of results; null when on the last page.\n required:\n - next\n StoredActionRecordListMeta:\n type: object\n description: Limit-offset pagination metadata for a Stored Action list response.\n properties:\n limit:\n type: integer\n description: Number of results returned in this response.\n offset:\n type: integer\n description: Starting index for this page of results.\n count:\n type: integer\n description: Total number of results across all pages.\n required:\n - count\n - limit\n - offset\n StoredActionRecordListResponse:\n type: object\n properties:\n results:\n type: array\n items:\n $ref: '#/components/schemas/StoredActionRecord'\n description: Stored actions belonging to the caller.\n meta:\n $ref: '#/components/schemas/StoredActionRecordListMeta'\n links:\n $ref: '#/components/schemas/StoredActionRecordListLinks'\n required:\n - links\n - meta\n - results\n StoredActionResult:\n type: object\n description: The flat response payload for fetching a stored action run.\n properties:\n type:\n type: string\n default: run\n description: Specifies the resource type, as required by the JSON:API specification.\n id:\n type: string\n format: uuid\n description: The id returned by the initial call to run an action.\n status:\n allOf:\n - $ref: '#/components/schemas/StatusA45Enum'\n description: 'The result of the action call itself from the partner. You\n could have a success=True (Zapier succeeded) and status=error (the partner\n raise an error).\n\n\n * `error` - error\n\n * `success` - success\n\n * `waiting` - waiting'\n results:\n type: array\n items:\n type: object\n additionalProperties: {}\n description: Could be empty, even if the action was successfully run.\n next_page:\n type: string\n description: When using bulk read action types, this denotes the state of\n the paging utilities. Pass it back as `page` on the next POST /stored-actions/{stored_action_id}/run\n call.\n errors:\n type: array\n items:\n $ref: '#/components/schemas/ActionsFetchError'\n description: Any errors returned by the partner when running this action.\n required:\n - errors\n StoredActionUpdateRequestParams:\n type: object\n description: 'The shape of the payload representing the fields available to\n update\n\n a StoredAction.\n\n\n You should delete your existing StoredAction and create a new record\n\n if you need to change either the connection_id or the selected_api.'\n properties:\n action_key:\n type: string\n description: Name of the action in the integration. Such as `new_contact`.\n action_type:\n allOf:\n - $ref: '#/components/schemas/ActionTypeEnum'\n description: 'Specifies the type of action in the integration since some\n integrations could have similarly named actions with different actions\n types\n\n\n * `read` - Read\n\n * `read_bulk` - Read Bulk\n\n * `write` - Write\n\n * `run` - Run\n\n * `search` - Search\n\n * `search_or_write` - Search Or Write\n\n * `search_and_write` - Search And Write\n\n * `filter` - Filter\n\n * `tool` - Tool'\n inputs:\n default: {}\n description: Object that matches the input the action would normally get.\n Has all the same keys/types as the `input` of the action. (Formerly known\n as \"needs\" in some documentation)\n StoredActionsCreateRequest:\n type: object\n properties:\n data:\n $ref: '#/components/schemas/StoredActionsCreateRequestParams'\n required:\n - data\n StoredActionsCreateRequestParams:\n type: object\n description: 'The shape of the payload that must be sent to create a Stored\n Action.\n\n\n Only the triple (selected_api, action_type, action_key) is accepted —\n\n `action_id` is intentionally not exposed on this endpoint.'\n properties:\n connection_id:\n type: string\n format: uuid\n description: UUID of the connection to use when executing the Stored Action.\n Can be any connection visible to the user (including shared).\n selected_api:\n type: string\n description: Something like `SlackAPI` (for Python apps) or `SplitwiseCLIAPI@1.0.0`\n (for CLI apps). Non-public apps are fine as long as the authed user can\n access them. If a version is included we attempt to use that version of\n the integration. If no version is provided we attempt to use the latest\n version of the integration\n action_key:\n type: string\n description: Name of the action in the integration. Such as `new_contact`.\n action_type:\n allOf:\n - $ref: '#/components/schemas/ActionTypeEnum'\n description: 'Specifies the type of action in the integration since some\n integrations could have similarly named actions with different actions\n types\n\n\n * `read` - Read\n\n * `read_bulk` - Read Bulk\n\n * `write` - Write\n\n * `run` - Run\n\n * `search` - Search\n\n * `search_or_write` - Search Or Write\n\n * `search_and_write` - Search And Write\n\n * `filter` - Filter\n\n * `tool` - Tool'\n inputs:\n default: {}\n description: Object that matches the input the action would normally get.\n Has all the same keys/types as the `input` of the action. (Formerly known\n as \"needs\" in some documentation)\n required:\n - action_key\n - action_type\n - selected_api\n StoredActionsCreateResponse:\n type: object\n description: The response returned from creating a Stored Action record.\n properties:\n type:\n type: string\n default: stored_action\n description: Specifies the resource type, as required by the JSON:API specification.\n id:\n type: string\n format: uuid\n description: The UUID id that identifies this stored action and can be used\n to execute the stored procedure by calling the POST /stored-actions/{stored_action_id}/run\n endpoint.\n required:\n - id\n StoredActionsRunRequest:\n type: object\n properties:\n data:\n $ref: '#/components/schemas/StoredActionsRunRequestInput'\n required:\n - data\n StoredActionsRunRequestInput:\n type: object\n description: The shape of a request payload accepted when running a stored action.\n properties:\n callback_url:\n type: string\n format: uri\n description: An optional URL that Zapier will POST the results to when the\n action completes. The POST body will match the same format as the GET\n /stored-actions/{stored_action_id}/runs/{run_id} response.\n maxLength: 2048\n idempotency_id:\n type: string\n format: uuid\n description: A client-provided UUID that identifies this specific request.\n If the same idempotency_id is used within 72 hours, the second request\n will be ignored and the original response returned.\n inputs:\n default: {}\n description: Object that matches the input the action would normally get.\n Has all the same keys/types as the `input` of the action. (Formerly known\n as \"needs\" in some documentation) Specifically includes more \"dynamic\"\n information to execute such as a specific message when triggering an action\n that sends a Slack DM, for example.\n page:\n type: string\n description: 'When using bulk read action types, this denotes the state\n of the paging utilities. Pass it back into the stored-actions endpoint. '\n StoredActionsRunResponse:\n type: object\n properties:\n data:\n $ref: '#/components/schemas/StoredActionsRunResponseParams'\n required:\n - data\n StoredActionsRunResponseParams:\n type: object\n description: The data returned after running a stored action\n properties:\n type:\n type: string\n default: run\n description: Specifies the resource type, as required by the JSON:API specification.\n id:\n type: string\n format: uuid\n description: The UUID id that identifies this run of the execution and can\n be used to retrieve the results by polling the GET /stored-actions/{stored_action_id}/runs/{run_id}\n endpoint.\n securitySchemes:\n OAuth:\n type: oauth2\n description: OAuth 2.0 authentication.\n flows:\n authorizationCode:\n authorizationUrl: https://zapier.com/oauth/authorize\n tokenUrl: https://zapier.com/oauth/token\n scopes:\n external: Scope that gives access to all Public APIs\n clientCredentials:\n tokenUrl: https://zapier.com/oauth/token\n scopes:\n external: Scope that gives access to all Public APIs\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/api-reference/specs/actions.yaml", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "openapi"], "related": [], "meta": {"title": "Actions API", "version": "v1", "servers": ["https://api.zapier.com"], "path_count": 4}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:liststoredactions", "kind": "api_function", "key": "listStoredActions", "title": "GET /actions/v1/stored-actions — List stored actions", "summary": "List stored actions", "body": "# `listStoredActions`\n\n> List stored actions\n\n## High-level description\n\nStored Actions endpoints handle the creation, execution, updates, and deletions\nof single created actions.\n\n## Internals\n\n`GET https://api.zapier.com/actions/v1/stored-actions` from **Actions API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n // no parameters\n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"Success: Includes all the Stored Actions for the caller. This could be an empty list.\",\n \"400\": \"Indicates an error executing the request to list Stored Actions.\",\n \"403\": \"Permission denied. Unauthorized request.\",\n \"429\": \"Too many requests.\",\n \"500\": \"Internal Server Error\",\n \"503\": \"Service Unavailable\"\n}\n```\n\n- Tags: Stored Actions\n- Security: [{\"OAuth\": [\"external\"]}]\n\n## Example\n\n```http\nGET /actions/v1/stored-actions HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "GET /actions/v1/stored-actions", "signature": "GET /actions/v1/stored-actions", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "openapi", "stored-actions"], "related": [], "meta": {"method": "GET", "path": "/actions/v1/stored-actions", "spec": "actions.yaml", "api_title": "Actions API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"200": "Success: Includes all the Stored Actions for the caller. This could be an empty list.", "400": "Indicates an error executing the request to list Stored Actions.", "403": "Permission denied. Unauthorized request.", "429": "Too many requests.", "500": "Internal Server Error", "503": "Service Unavailable"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:createstoredaction", "kind": "api_function", "key": "createStoredAction", "title": "POST /actions/v1/stored-actions — Create a stored action", "summary": "Create a stored action", "body": "# `createStoredAction`\n\n> Create a stored action\n\n## High-level description\n\nCreate Stored Action\n\nCreates a new stored action entry that can then be executed from a simpler call to\n/stored-actions with just the stored action `id`.\n\nThis will not execute a StoredAction.\n\nThis is an async process and will only respond with the id of the stored action and other meta data,\nand it is the callers responsibility to poll\nGET /stored-actions/{stored_action_id}/runs/{run_id} with the run id returned from\nPOST /stored-actions/{stored_action_id}/run to fetch the results after executing a stored action.\n\nThe triple (selected_api, action_type, action_key) is required to create a stored action.\nOnly core actions are supported; external and custom (App Extension) actions cannot be\ncreated as stored actions via this endpoint.\n\n**Note on `connection_id`:** Other Zapier APIs may expose the same\nidentifier under the field name `authentication_id`. The value is the\nsame UUID — pass it here under the `connection_id` key.\n\n## Internals\n\n`POST https://api.zapier.com/actions/v1/stored-actions` from **Actions API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n body?: StoredActionsCreateRequest; // request JSON\n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"A StoredAction record was successfully created.\",\n \"400\": \"Indicates an error creating a StoredAction record.\",\n \"403\": \"Permission denied. Unauthorized request.\",\n \"429\": \"Too many requests.\",\n \"500\": \"Internal Server Error\",\n \"503\": \"Service Unavailable\"\n}\n```\n\n- Tags: Stored Actions\n- Security: [{\"OAuth\": [\"external\"]}]\n\n## Example\n\n```http\nPOST /actions/v1/stored-actions HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "POST /actions/v1/stored-actions", "signature": "POST /actions/v1/stored-actions", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "openapi", "stored-actions"], "related": [], "meta": {"method": "POST", "path": "/actions/v1/stored-actions", "spec": "actions.yaml", "api_title": "Actions API", "servers": ["https://api.zapier.com"], "request_schema": {"$ref": "#/components/schemas/StoredActionsCreateRequest"}, "responses": {"200": "A StoredAction record was successfully created.", "400": "Indicates an error creating a StoredAction record.", "403": "Permission denied. Unauthorized request.", "429": "Too many requests.", "500": "Internal Server Error", "503": "Service Unavailable"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:getstoredaction", "kind": "api_function", "key": "getStoredAction", "title": "GET /actions/v1/stored-actions/{stored_action_id} — Get a stored action", "summary": "Get a stored action", "body": "# `getStoredAction`\n\n> Get a stored action\n\n## High-level description\n\nStored Actions endpoints handle the creation, execution, updates, and deletions\nof single created actions.\n\n## Internals\n\n`GET https://api.zapier.com/actions/v1/stored-actions/{stored_action_id}` from **Actions API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n stored_action_id: string; // in path — \n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"Success: Includes data for the requested Stored Action.\",\n \"400\": \"Imporoperly formatted or incomplete request.\",\n \"404\": \"No results found for this Stored Action id.\",\n \"403\": \"Permission denied. Unauthorized request.\",\n \"429\": \"Too many requests.\",\n \"500\": \"Internal Server Error\",\n \"503\": \"Service Unavailable\"\n}\n```\n\n- Tags: Stored Actions\n- Security: [{\"OAuth\": [\"external\"]}]\n\n## Example\n\n```http\nGET /actions/v1/stored-actions/{stored_action_id} HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "GET /actions/v1/stored-actions/{stored_action_id}", "signature": "GET /actions/v1/stored-actions/{stored_action_id}", "aliases": [], "flags": [], "args": [{"name": "stored_action_id", "in": "path", "required": true, "type": "string", "description": ""}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "openapi", "stored-actions"], "related": [], "meta": {"method": "GET", "path": "/actions/v1/stored-actions/{stored_action_id}", "spec": "actions.yaml", "api_title": "Actions API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"200": "Success: Includes data for the requested Stored Action.", "400": "Imporoperly formatted or incomplete request.", "404": "No results found for this Stored Action id.", "403": "Permission denied. Unauthorized request.", "429": "Too many requests.", "500": "Internal Server Error", "503": "Service Unavailable"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:updatestoredaction", "kind": "api_function", "key": "updateStoredAction", "title": "PATCH /actions/v1/stored-actions/{stored_action_id} — Update a stored action", "summary": "Update a stored action", "body": "# `updateStoredAction`\n\n> Update a stored action\n\n## High-level description\n\nStored Actions endpoints handle the creation, execution, updates, and deletions\nof single created actions.\n\n## Internals\n\n`PATCH https://api.zapier.com/actions/v1/stored-actions/{stored_action_id}` from **Actions API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n stored_action_id: string; // in path — \n body?: PatchedStoredActionsUpdateRequest; // request JSON\n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"A StoredAction record was successfully updated.\",\n \"400\": \"Indicates an error updating a StoredAction record.\",\n \"403\": \"Permission denied. Unauthorized request.\",\n \"429\": \"Too many requests.\",\n \"500\": \"Internal Server Error\",\n \"503\": \"Service Unavailable\"\n}\n```\n\n- Tags: Stored Actions\n- Security: [{\"OAuth\": [\"external\"]}]\n\n## Example\n\n```http\nPATCH /actions/v1/stored-actions/{stored_action_id} HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "PATCH /actions/v1/stored-actions/{stored_action_id}", "signature": "PATCH /actions/v1/stored-actions/{stored_action_id}", "aliases": [], "flags": [], "args": [{"name": "stored_action_id", "in": "path", "required": true, "type": "string", "description": ""}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "openapi", "stored-actions"], "related": [], "meta": {"method": "PATCH", "path": "/actions/v1/stored-actions/{stored_action_id}", "spec": "actions.yaml", "api_title": "Actions API", "servers": ["https://api.zapier.com"], "request_schema": {"$ref": "#/components/schemas/PatchedStoredActionsUpdateRequest"}, "responses": {"200": "A StoredAction record was successfully updated.", "400": "Indicates an error updating a StoredAction record.", "403": "Permission denied. Unauthorized request.", "429": "Too many requests.", "500": "Internal Server Error", "503": "Service Unavailable"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:deletestoredaction", "kind": "api_function", "key": "deleteStoredAction", "title": "DELETE /actions/v1/stored-actions/{stored_action_id} — Delete a stored action", "summary": "Delete a stored action", "body": "# `deleteStoredAction`\n\n> Delete a stored action\n\n## High-level description\n\nStored Actions endpoints handle the creation, execution, updates, and deletions\nof single created actions.\n\n## Internals\n\n`DELETE https://api.zapier.com/actions/v1/stored-actions/{stored_action_id}` from **Actions API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n stored_action_id: string; // in path — \n};\n```\n\n## Outputs\n\n```json\n{\n \"204\": \"A StoredAction record was successfully deleted.\",\n \"400\": \"Indicates an error deleting a StoredAction record.\",\n \"403\": \"Permission denied. Unauthorized request.\",\n \"429\": \"Too many requests.\",\n \"500\": \"Internal Server Error\",\n \"503\": \"Service Unavailable\"\n}\n```\n\n- Tags: Stored Actions\n- Security: [{\"OAuth\": [\"external\"]}]\n\n## Example\n\n```http\nDELETE /actions/v1/stored-actions/{stored_action_id} HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "DELETE /actions/v1/stored-actions/{stored_action_id}", "signature": "DELETE /actions/v1/stored-actions/{stored_action_id}", "aliases": [], "flags": [], "args": [{"name": "stored_action_id", "in": "path", "required": true, "type": "string", "description": ""}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "openapi", "stored-actions"], "related": [], "meta": {"method": "DELETE", "path": "/actions/v1/stored-actions/{stored_action_id}", "spec": "actions.yaml", "api_title": "Actions API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"204": "A StoredAction record was successfully deleted.", "400": "Indicates an error deleting a StoredAction record.", "403": "Permission denied. Unauthorized request.", "429": "Too many requests.", "500": "Internal Server Error", "503": "Service Unavailable"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:createstoredactionrun", "kind": "api_function", "key": "createStoredActionRun", "title": "POST /actions/v1/stored-actions/{stored_action_id}/run — Run a stored action", "summary": "Run a stored action", "body": "# `createStoredActionRun`\n\n> Run a stored action\n\n## High-level description\n\nExecute Stored Action\n\nExecutes an action on behalf of a user, this is an async process.\n\nRequires the id from a stored action\n\nResponds with the unique id for this run of the stored action. In order to fetch results\nyou will need to poll the GET /stored-actions/{stored_action_id}/runs/{run_id} endpoint\nwith that run id.\n\n**Billing**\n\nThe Actions API offers support for directly billing users for Stored Action\nRuns, and this functionality is currently _opt-in_. To do this, you\nmust provide a `billing` claim on the JWT used to authenticate. This\nclaim must be a JSON string, and any values provided will override the\ndefault configuration shown below. The simplest approach is therefore\nto set `is_billable` to true, and successful Stored Action Runs will be\ncharged to a user at a rate of one task.\n\n```json\nbilling: {\n \"is_billable\": false,\n \"origin\": \"actions_api\",\n \"usage_type\": \"action_run\",\n \"description\": \"an action was run via Actions API\",\n \"exemption_reason\": null,\n \"exemption_details\": null\n}\n```\n\n**Rate Limits**\n\nRate limiting is applied when Gargoyle flag `edge_actions_api_rate_limiting_global`\nis active. Requests are rate limited by default unless the JWT explicitly sets\n`rate_limit.exempt` to true.\n\n```json\nrate_limit: {\n \"exempt\": true\n}\n```\n\nNon-exempted requests are limited to 200 per 5 minutes by default. To set a custom\nlimit, include `limit_override` (11000 requests per 5 minutes):\n\n```json\nrate_limit: {\n \"exempt\": false,\n \"limit_override\": 500\n}\n```\n\n## Internals\n\n`POST https://api.zapier.com/actions/v1/stored-actions/{stored_action_id}/run` from **Actions API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n stored_action_id: string; // in path — \n body?: StoredActionsRunRequest; // request JSON\n};\n```\n\n## Outputs\n\n```json\n{\n \"202\": \"Acknowledges the request to execute a StoredAction\",\n \"400\": \"Indicates an error executing the request to run a StoredAction.\",\n \"403\": \"Permission denied. Unauthorized request.\",\n \"429\": \"Too many requests.\",\n \"500\": \"Internal Server Error\",\n \"503\": \"Service Unavailable\",\n \"402\": \"Payment Required - insufficient tasks on account\",\n \"424\": \"Failed Dependency - the partner API is temporarily unhealthy\"\n}\n```\n\n- Tags: Stored Actions\n- Security: [{\"OAuth\": [\"external\"]}]\n\n## Example\n\n```http\nPOST /actions/v1/stored-actions/{stored_action_id}/run HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "POST /actions/v1/stored-actions/{stored_action_id}/run", "signature": "POST /actions/v1/stored-actions/{stored_action_id}/run", "aliases": [], "flags": [], "args": [{"name": "stored_action_id", "in": "path", "required": true, "type": "string", "description": ""}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "openapi", "stored-actions"], "related": [], "meta": {"method": "POST", "path": "/actions/v1/stored-actions/{stored_action_id}/run", "spec": "actions.yaml", "api_title": "Actions API", "servers": ["https://api.zapier.com"], "request_schema": {"$ref": "#/components/schemas/StoredActionsRunRequest"}, "responses": {"202": "Acknowledges the request to execute a StoredAction", "400": "Indicates an error executing the request to run a StoredAction.", "403": "Permission denied. Unauthorized request.", "429": "Too many requests.", "500": "Internal Server Error", "503": "Service Unavailable", "402": "Payment Required - insufficient tasks on account", "424": "Failed Dependency - the partner API is temporarily unhealthy"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:getstoredactionrun", "kind": "api_function", "key": "getStoredActionRun", "title": "GET /actions/v1/stored-actions/{stored_action_id}/runs/{run_id} — Get stored action run results", "summary": "Get stored action run results", "body": "# `getStoredActionRun`\n\n> Get stored action run results\n\n## High-level description\n\nFetch Stored Action Run\n\nRequires the id returned from a call to /stored-actions/{stored_action_id}/run\nto execute the stored action.\n\nThe status code returned by this call does NOT denote the status of the action\nin an external system, but the status of the action processing from Zapier.\n\nResults are stored for seven days after the action was initially executed.\n\n## Internals\n\n`GET https://api.zapier.com/actions/v1/stored-actions/{stored_action_id}/runs/{run_id}` from **Actions API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n run_id: string; // in path — \n stored_action_id: string; // in path — \n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"Success: Includes the results of the task run.\",\n \"202\": \"The request is still processing, try fetching results again later.\",\n \"400\": \"Imporoperly formatted or incomplete request.\",\n \"404\": \"No results found for this run.\",\n \"403\": \"Permission denied. Unauthorized request.\",\n \"429\": \"Too many requests.\",\n \"500\": \"Internal Server Error\",\n \"503\": \"Service Unavailable\"\n}\n```\n\n- Tags: Stored Actions\n- Security: [{\"OAuth\": [\"external\"]}]\n\n## Example\n\n```http\nGET /actions/v1/stored-actions/{stored_action_id}/runs/{run_id} HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "GET /actions/v1/stored-actions/{stored_action_id}/runs/{run_id}", "signature": "GET /actions/v1/stored-actions/{stored_action_id}/runs/{run_id}", "aliases": [], "flags": [], "args": [{"name": "run_id", "in": "path", "required": true, "type": "string", "description": ""}, {"name": "stored_action_id", "in": "path", "required": true, "type": "string", "description": ""}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "openapi", "stored-actions"], "related": [], "meta": {"method": "GET", "path": "/actions/v1/stored-actions/{stored_action_id}/runs/{run_id}", "spec": "actions.yaml", "api_title": "Actions API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"200": "Success: Includes the results of the task run.", "202": "The request is still processing, try fetching results again later.", "400": "Imporoperly formatted or incomplete request.", "404": "No results found for this run.", "403": "Permission denied. Unauthorized request.", "429": "Too many requests.", "500": "Internal Server Error", "503": "Service Unavailable"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "openapi:connections.yaml", "kind": "openapi", "key": "connections.yaml", "title": "Connections API (connections.yaml)", "summary": "Register and manage webhook subscriptions for the connections your White Label (partner) account manages. Receive a signed event whenever one of those connections expires and needs to be reconnected.", "body": "openapi: 3.1.0\ninfo:\n title: Connections API\n description: Register and manage webhook subscriptions for the connections your\n White Label (partner) account manages. Receive a signed event whenever one of\n those connections expires and needs to be reconnected.\n version: v1\n contact:\n url: https://docs.zapier.com\nservers:\n - url: https://api.zapier.com\n description: Production\ntags:\n - name: Connection Webhooks\n description: Operations for managing per-partner webhook subscriptions for connection\n events\nsecurity:\n - OAuth: []\npaths:\n /connections/v1/webhooks:\n get:\n operationId: listConnectionWebhooks\n description: List the caller's connection webhooks (active and paused).\n summary: List connection webhooks\n parameters:\n - in: query\n name: event_type\n schema:\n type: string\n enum:\n - connection.expiry_scheduled\n description: Filter by event type.\n - in: query\n name: is_active\n schema:\n type: boolean\n description: Filter by active/paused state.\n - in: query\n name: limit\n schema:\n type: integer\n description: Number of results to return per page.\n - in: query\n name: offset\n schema:\n type: integer\n description: The initial index from which to return the results.\n tags:\n - Connection Webhooks\n security:\n - OAuth:\n - connection:webhook:read\n - external\n responses:\n '200':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/PaginatedConnectionWebhookList'\n description: A page of connection webhooks.\n '400':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: 'Validation Error: Return fields with errors.'\n post:\n operationId: createConnectionWebhook\n description: Register an HTTPS endpoint to receive signed events for connections\n managed by the caller's partner (HQ) account. The signing `secret` is returned\n ONCE in this response and never again. Store it securely.\n summary: Create a connection webhook\n tags:\n - Connection Webhooks\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ConnectionWebhookCreate'\n examples:\n SubscribeToConnectionExpiryEvents:\n value:\n event_type: connection.expiry_scheduled\n callback_url: https://example.com/webhooks/zapier\n summary: Subscribe to connection expiry events\n required: true\n security:\n - OAuth:\n - connection:webhook:write\n - external\n responses:\n '201':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ConnectionWebhookWithSecret'\n description: Created. Includes the signing secret (shown once).\n '400':\n description: Invalid request.\n '409':\n description: An active webhook for this event type already exists.\n callbacks:\n connectionEvent:\n '{$request.body#/callback_url}':\n post:\n description: 'When a subscribed event occurs, Zapier sends a signed\n HTTPS `POST` to the `callback_url` registered on this webhook. Requests\n are signed following the [Standard Webhooks](https://www.standardwebhooks.com/)\n specification — verify the `webhook-signature` header using the `secret`\n returned once at creation. Respond with any `2xx` status to acknowledge;\n non-`2xx` responses, timeouts, and `429`s are retried with backoff.\n\n\n Each request carries three headers used for signature verification.\n `webhook-id` is a stable delivery ID for the event that stays constant\n across retries (use it to deduplicate). `webhook-timestamp` is the\n Unix epoch, in seconds, at which the event was signed. `webhook-signature`\n is a space-delimited list of `v1,<base64 HMAC-SHA256>` signatures\n computed over `{webhook-id}.{webhook-timestamp}.{body}`.'\n summary: Connection event notification\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ConnectionWebhookEvent'\n required: true\n responses:\n '200':\n description: Event acknowledged. Any `2xx` status is accepted.\n /connections/v1/webhooks/{id}:\n get:\n operationId: getConnectionWebhook\n description: 'CRUD API for per-partner webhook subscriptions.\n\n\n Scoped to the caller''s HQ account: a partner can only read and mutate\n\n its own webhooks. ``hq_account_id`` is always derived from the\n\n authenticated identity, never accepted from the request body.'\n summary: Retrieve a connection webhook\n parameters:\n - in: path\n name: id\n schema:\n type: string\n format: uuid\n description: UUID of the connection webhook.\n required: true\n tags:\n - Connection Webhooks\n security:\n - OAuth:\n - connection:webhook:read\n - external\n responses:\n '200':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ConnectionWebhook'\n description: The connection webhook.\n '404':\n description: Not found.\n '400':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: 'Validation Error: Return fields with errors.'\n patch:\n operationId: updateConnectionWebhook\n description: Update `callback_url` and/or pause/resume via `is_active`. `event_type`\n is immutable.\n summary: Update a connection webhook\n parameters:\n - in: path\n name: id\n schema:\n type: string\n format: uuid\n description: UUID of the connection webhook.\n required: true\n tags:\n - Connection Webhooks\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/PatchedConnectionWebhookUpdate'\n examples:\n PauseDelivery:\n value:\n is_active: false\n summary: Pause delivery\n UpdateTheCallbackURL:\n value:\n callback_url: https://example.com/webhooks/zapier-v2\n summary: Update the callback URL\n security:\n - OAuth:\n - connection:webhook:write\n - external\n responses:\n '200':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ConnectionWebhook'\n description: Updated.\n '400':\n description: Invalid request.\n '404':\n description: Not found.\n delete:\n operationId: deleteConnectionWebhook\n description: 'CRUD API for per-partner webhook subscriptions.\n\n\n Scoped to the caller''s HQ account: a partner can only read and mutate\n\n its own webhooks. ``hq_account_id`` is always derived from the\n\n authenticated identity, never accepted from the request body.'\n summary: Delete a connection webhook\n parameters:\n - in: path\n name: id\n schema:\n type: string\n format: uuid\n description: UUID of the connection webhook.\n required: true\n tags:\n - Connection Webhooks\n security:\n - OAuth:\n - connection:webhook:write\n - external\n responses:\n '204':\n description: Deleted.\n '404':\n description: Not found.\n '400':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: 'Validation Error: Return fields with errors.'\n /connections/v1/webhooks/{id}/test:\n post:\n operationId: createConnectionWebhookTest\n description: 'Trigger a sample (synthetic) `connection.expiry_scheduled` delivery\n to this webhook''s `callback_url`, so you can validate your handler and signature\n verification before relying on real events. The delivered payload is a synthetic\n example and is clearly marked as a test. In addition to the `webhook-id`,\n `webhook-timestamp`, and `webhook-signature` headers sent on every delivery,\n a test delivery also carries a `webhook-test: true` header.'\n summary: Send a test delivery\n parameters:\n - in: path\n name: id\n schema:\n type: string\n format: uuid\n description: UUID of the connection webhook.\n required: true\n tags:\n - Connection Webhooks\n security:\n - OAuth:\n - connection:webhook:write\n - external\n responses:\n '202':\n description: Test delivery enqueued.\n '404':\n description: Not found.\n '400':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: 'Validation Error: Return fields with errors.'\ncomponents:\n schemas:\n ConnectionWebhook:\n type: object\n description: Output serializer for GET / PATCH responses. Secret is never returned.\n properties:\n id:\n type: string\n format: uuid\n readOnly: true\n description: Unique webhook identifier (UUID).\n event_type:\n allOf:\n - $ref: '#/components/schemas/EventTypeEnum'\n readOnly: true\n description: 'The event type this webhook is subscribed to.\n\n\n * `connection.expiry_scheduled` - Expiry Scheduled'\n callback_url:\n type: string\n format: uri\n readOnly: true\n description: HTTPS URL that signed events are POSTed to.\n is_active:\n type: boolean\n readOnly: true\n description: Whether the webhook is active. Inactive webhooks do not receive\n events.\n created_at:\n type: string\n format: date-time\n readOnly: true\n description: ISO 8601 timestamp when the webhook was created.\n updated_at:\n type: string\n format: date-time\n readOnly: true\n description: ISO 8601 timestamp when the webhook was last updated.\n required:\n - callback_url\n - created_at\n - event_type\n - id\n - is_active\n - updated_at\n ConnectionWebhookCreate:\n type: object\n description: Input serializer for POST /webhooks.\n properties:\n event_type:\n allOf:\n - $ref: '#/components/schemas/EventTypeEnum'\n description: 'The event to subscribe to.\n\n\n * `connection.expiry_scheduled` - Expiry Scheduled'\n callback_url:\n type: string\n format: uri\n description: HTTPS URL that signed events are POSTed to.\n required:\n - callback_url\n - event_type\n ConnectionWebhookEvent:\n type: object\n description: Outbound event payload POSTed to ``callback_url`` (documentation\n only).\n properties:\n type:\n allOf:\n - $ref: '#/components/schemas/TypeEnum'\n description: 'The event type. Matches the `event_type` this webhook subscribed\n to.\n\n\n * `connection.expiry_scheduled` - Expiry Scheduled'\n expires_at:\n type: string\n format: date-time\n description: ISO 8601 timestamp when the connection is scheduled to expire.\n data:\n allOf:\n - $ref: '#/components/schemas/ConnectionWebhookEventData'\n description: Event-specific details.\n required:\n - data\n - expires_at\n - type\n ConnectionWebhookEventData:\n type: object\n description: The ``data`` object of an outbound connection event (documentation\n only).\n properties:\n connection_id:\n type: string\n description: External (opaque) ID of the connection that triggered the event.\n account_id:\n type: string\n description: External (opaque) ID of the account that owns the connection.\n app:\n type: string\n description: The integration the connection belongs to, as `app_key@version`\n (e.g. `SlackAPI@1.0.0`).\n title:\n type: string\n description: Human-readable title of the connection.\n required:\n - account_id\n - app\n - connection_id\n - title\n ConnectionWebhookWithSecret:\n type: object\n description: Output serializer for POST 201. Includes the signing secret (returned\n once only).\n properties:\n id:\n type: string\n format: uuid\n readOnly: true\n description: Unique webhook identifier (UUID).\n event_type:\n allOf:\n - $ref: '#/components/schemas/EventTypeEnum'\n readOnly: true\n description: 'The event type this webhook is subscribed to.\n\n\n * `connection.expiry_scheduled` - Expiry Scheduled'\n callback_url:\n type: string\n format: uri\n readOnly: true\n description: HTTPS URL that signed events are POSTed to.\n is_active:\n type: boolean\n readOnly: true\n description: Whether the webhook is active. Inactive webhooks do not receive\n events.\n created_at:\n type: string\n format: date-time\n readOnly: true\n description: ISO 8601 timestamp when the webhook was created.\n updated_at:\n type: string\n format: date-time\n readOnly: true\n description: ISO 8601 timestamp when the webhook was last updated.\n secret:\n type: string\n readOnly: true\n description: Standard Webhooks signing secret (whsec_…). Shown once, at\n creation.\n required:\n - callback_url\n - created_at\n - event_type\n - id\n - is_active\n - secret\n - updated_at\n ErrorDetail:\n type: object\n description: 'Per the schema defined in the engineering index.\n\n\n https://engineering.zapier.com/guides/api-design-guidelines/error-handling/'\n properties:\n code:\n type: string\n description: A unique identifier for this particular occurrence of the problem.\n detail:\n type: string\n description: A human-readable explanation specific to this occurrence of\n the problem.\n status:\n type: integer\n description: HTTP status code for that error.\n title:\n type: string\n description: A short summary of the problem.\n source:\n type: object\n additionalProperties: {}\n description: An object containing references to the primary source of the\n error.\n required:\n - code\n - detail\n Errors:\n type: object\n properties:\n errors:\n type: array\n items:\n $ref: '#/components/schemas/ErrorDetail'\n description: An array of error objects.\n required:\n - errors\n EventTypeEnum:\n enum:\n - connection.expiry_scheduled\n type: string\n description: '* `connection.expiry_scheduled` - Expiry Scheduled'\n PaginatedConnectionWebhookList:\n type: object\n required:\n - links\n - meta\n - results\n properties:\n results:\n description: Connection webhooks for the current page.\n type: array\n items:\n $ref: '#/components/schemas/ConnectionWebhook'\n meta:\n type: object\n description: Limit-offset pagination metadata.\n required:\n - count\n - limit\n - offset\n properties:\n limit:\n type: integer\n description: Number of results returned per page.\n offset:\n type: integer\n description: Starting index for this page of results.\n count:\n type: integer\n description: Total number of results across all pages.\n links:\n type: object\n description: Pagination navigation links.\n required:\n - next\n properties:\n next:\n type:\n - string\n - 'null'\n format: uri\n description: Link to the next page of results; null when on the last\n page.\n PatchedConnectionWebhookUpdate:\n type: object\n description: Input serializer for PATCH /webhooks/{id}. At least one field required.\n properties:\n callback_url:\n type: string\n format: uri\n description: New HTTPS URL for event delivery.\n is_active:\n type: boolean\n description: Pause (false) or resume (true) delivery.\n TypeEnum:\n enum:\n - connection.expiry_scheduled\n type: string\n description: '* `connection.expiry_scheduled` - Expiry Scheduled'\n securitySchemes:\n OAuth:\n type: oauth2\n description: OAuth 2.0 authentication.\n flows:\n authorizationCode:\n authorizationUrl: https://zapier.com/oauth/authorize\n tokenUrl: https://zapier.com/oauth/token\n scopes:\n connection:webhook:read: Grants connection:webhook:read access\n external: Scope that gives access to all Public APIs\n connection:webhook:write: Grants connection:webhook:write access\n clientCredentials:\n tokenUrl: https://zapier.com/oauth/token\n scopes:\n connection:webhook:read: Grants connection:webhook:read access\n external: Scope that gives access to all Public APIs\n connection:webhook:write: Grants connection:webhook:write access\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/api-reference/specs/connections.yaml", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "openapi"], "related": [], "meta": {"title": "Connections API", "version": "v1", "servers": ["https://api.zapier.com"], "path_count": 3}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:listconnectionwebhooks", "kind": "api_function", "key": "listConnectionWebhooks", "title": "GET /connections/v1/webhooks — List connection webhooks", "summary": "List connection webhooks", "body": "# `listConnectionWebhooks`\n\n> List connection webhooks\n\n## High-level description\n\nList the caller's connection webhooks (active and paused).\n\n## Internals\n\n`GET https://api.zapier.com/connections/v1/webhooks` from **Connections API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n event_type?: string; // in query — Filter by event type.\n is_active?: boolean; // in query — Filter by active/paused state.\n limit?: integer; // in query — Number of results to return per page.\n offset?: integer; // in query — The initial index from which to return the results.\n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"A page of connection webhooks.\",\n \"400\": \"Validation Error: Return fields with errors.\"\n}\n```\n\n- Tags: Connection Webhooks\n- Security: [{\"OAuth\": [\"connection:webhook:read\", \"external\"]}]\n\n## Example\n\n```http\nGET /connections/v1/webhooks HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "GET /connections/v1/webhooks", "signature": "GET /connections/v1/webhooks", "aliases": [], "flags": [], "args": [{"name": "event_type", "in": "query", "required": false, "type": "string", "description": "Filter by event type."}, {"name": "is_active", "in": "query", "required": false, "type": "boolean", "description": "Filter by active/paused state."}, {"name": "limit", "in": "query", "required": false, "type": "integer", "description": "Number of results to return per page."}, {"name": "offset", "in": "query", "required": false, "type": "integer", "description": "The initial index from which to return the results."}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "connection-webhooks", "openapi"], "related": [], "meta": {"method": "GET", "path": "/connections/v1/webhooks", "spec": "connections.yaml", "api_title": "Connections API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"200": "A page of connection webhooks.", "400": "Validation Error: Return fields with errors."}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:createconnectionwebhook", "kind": "api_function", "key": "createConnectionWebhook", "title": "POST /connections/v1/webhooks — Create a connection webhook", "summary": "Create a connection webhook", "body": "# `createConnectionWebhook`\n\n> Create a connection webhook\n\n## High-level description\n\nRegister an HTTPS endpoint to receive signed events for connections managed by the caller's partner (HQ) account. The signing `secret` is returned ONCE in this response and never again. Store it securely.\n\n## Internals\n\n`POST https://api.zapier.com/connections/v1/webhooks` from **Connections API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n body?: ConnectionWebhookCreate; // request JSON\n};\n```\n\n## Outputs\n\n```json\n{\n \"201\": \"Created. Includes the signing secret (shown once).\",\n \"400\": \"Invalid request.\",\n \"409\": \"An active webhook for this event type already exists.\"\n}\n```\n\n- Tags: Connection Webhooks\n- Security: [{\"OAuth\": [\"connection:webhook:write\", \"external\"]}]\n\n## Example\n\n```http\nPOST /connections/v1/webhooks HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "POST /connections/v1/webhooks", "signature": "POST /connections/v1/webhooks", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "connection-webhooks", "openapi"], "related": [], "meta": {"method": "POST", "path": "/connections/v1/webhooks", "spec": "connections.yaml", "api_title": "Connections API", "servers": ["https://api.zapier.com"], "request_schema": {"$ref": "#/components/schemas/ConnectionWebhookCreate"}, "responses": {"201": "Created. Includes the signing secret (shown once).", "400": "Invalid request.", "409": "An active webhook for this event type already exists."}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:getconnectionwebhook", "kind": "api_function", "key": "getConnectionWebhook", "title": "GET /connections/v1/webhooks/{id} — Retrieve a connection webhook", "summary": "Retrieve a connection webhook", "body": "# `getConnectionWebhook`\n\n> Retrieve a connection webhook\n\n## High-level description\n\nCRUD API for per-partner webhook subscriptions.\n\nScoped to the caller's HQ account: a partner can only read and mutate\nits own webhooks. ``hq_account_id`` is always derived from the\nauthenticated identity, never accepted from the request body.\n\n## Internals\n\n`GET https://api.zapier.com/connections/v1/webhooks/{id}` from **Connections API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n id: string; // in path — UUID of the connection webhook.\n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"The connection webhook.\",\n \"404\": \"Not found.\",\n \"400\": \"Validation Error: Return fields with errors.\"\n}\n```\n\n- Tags: Connection Webhooks\n- Security: [{\"OAuth\": [\"connection:webhook:read\", \"external\"]}]\n\n## Example\n\n```http\nGET /connections/v1/webhooks/{id} HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "GET /connections/v1/webhooks/{id}", "signature": "GET /connections/v1/webhooks/{id}", "aliases": [], "flags": [], "args": [{"name": "id", "in": "path", "required": true, "type": "string", "description": "UUID of the connection webhook."}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "connection-webhooks", "openapi"], "related": [], "meta": {"method": "GET", "path": "/connections/v1/webhooks/{id}", "spec": "connections.yaml", "api_title": "Connections API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"200": "The connection webhook.", "404": "Not found.", "400": "Validation Error: Return fields with errors."}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:updateconnectionwebhook", "kind": "api_function", "key": "updateConnectionWebhook", "title": "PATCH /connections/v1/webhooks/{id} — Update a connection webhook", "summary": "Update a connection webhook", "body": "# `updateConnectionWebhook`\n\n> Update a connection webhook\n\n## High-level description\n\nUpdate `callback_url` and/or pause/resume via `is_active`. `event_type` is immutable.\n\n## Internals\n\n`PATCH https://api.zapier.com/connections/v1/webhooks/{id}` from **Connections API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n id: string; // in path — UUID of the connection webhook.\n body?: PatchedConnectionWebhookUpdate; // request JSON\n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"Updated.\",\n \"400\": \"Invalid request.\",\n \"404\": \"Not found.\"\n}\n```\n\n- Tags: Connection Webhooks\n- Security: [{\"OAuth\": [\"connection:webhook:write\", \"external\"]}]\n\n## Example\n\n```http\nPATCH /connections/v1/webhooks/{id} HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "PATCH /connections/v1/webhooks/{id}", "signature": "PATCH /connections/v1/webhooks/{id}", "aliases": [], "flags": [], "args": [{"name": "id", "in": "path", "required": true, "type": "string", "description": "UUID of the connection webhook."}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "connection-webhooks", "openapi"], "related": [], "meta": {"method": "PATCH", "path": "/connections/v1/webhooks/{id}", "spec": "connections.yaml", "api_title": "Connections API", "servers": ["https://api.zapier.com"], "request_schema": {"$ref": "#/components/schemas/PatchedConnectionWebhookUpdate"}, "responses": {"200": "Updated.", "400": "Invalid request.", "404": "Not found."}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:deleteconnectionwebhook", "kind": "api_function", "key": "deleteConnectionWebhook", "title": "DELETE /connections/v1/webhooks/{id} — Delete a connection webhook", "summary": "Delete a connection webhook", "body": "# `deleteConnectionWebhook`\n\n> Delete a connection webhook\n\n## High-level description\n\nCRUD API for per-partner webhook subscriptions.\n\nScoped to the caller's HQ account: a partner can only read and mutate\nits own webhooks. ``hq_account_id`` is always derived from the\nauthenticated identity, never accepted from the request body.\n\n## Internals\n\n`DELETE https://api.zapier.com/connections/v1/webhooks/{id}` from **Connections API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n id: string; // in path — UUID of the connection webhook.\n};\n```\n\n## Outputs\n\n```json\n{\n \"204\": \"Deleted.\",\n \"404\": \"Not found.\",\n \"400\": \"Validation Error: Return fields with errors.\"\n}\n```\n\n- Tags: Connection Webhooks\n- Security: [{\"OAuth\": [\"connection:webhook:write\", \"external\"]}]\n\n## Example\n\n```http\nDELETE /connections/v1/webhooks/{id} HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "DELETE /connections/v1/webhooks/{id}", "signature": "DELETE /connections/v1/webhooks/{id}", "aliases": [], "flags": [], "args": [{"name": "id", "in": "path", "required": true, "type": "string", "description": "UUID of the connection webhook."}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "connection-webhooks", "openapi"], "related": [], "meta": {"method": "DELETE", "path": "/connections/v1/webhooks/{id}", "spec": "connections.yaml", "api_title": "Connections API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"204": "Deleted.", "404": "Not found.", "400": "Validation Error: Return fields with errors."}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:createconnectionwebhooktest", "kind": "api_function", "key": "createConnectionWebhookTest", "title": "POST /connections/v1/webhooks/{id}/test — Send a test delivery", "summary": "Send a test delivery", "body": "# `createConnectionWebhookTest`\n\n> Send a test delivery\n\n## High-level description\n\nTrigger a sample (synthetic) `connection.expiry_scheduled` delivery to this webhook's `callback_url`, so you can validate your handler and signature verification before relying on real events. The delivered payload is a synthetic example and is clearly marked as a test. In addition to the `webhook-id`, `webhook-timestamp`, and `webhook-signature` headers sent on every delivery, a test delivery also carries a `webhook-test: true` header.\n\n## Internals\n\n`POST https://api.zapier.com/connections/v1/webhooks/{id}/test` from **Connections API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n id: string; // in path — UUID of the connection webhook.\n};\n```\n\n## Outputs\n\n```json\n{\n \"202\": \"Test delivery enqueued.\",\n \"404\": \"Not found.\",\n \"400\": \"Validation Error: Return fields with errors.\"\n}\n```\n\n- Tags: Connection Webhooks\n- Security: [{\"OAuth\": [\"connection:webhook:write\", \"external\"]}]\n\n## Example\n\n```http\nPOST /connections/v1/webhooks/{id}/test HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "POST /connections/v1/webhooks/{id}/test", "signature": "POST /connections/v1/webhooks/{id}/test", "aliases": [], "flags": [], "args": [{"name": "id", "in": "path", "required": true, "type": "string", "description": "UUID of the connection webhook."}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "connection-webhooks", "openapi"], "related": [], "meta": {"method": "POST", "path": "/connections/v1/webhooks/{id}/test", "spec": "connections.yaml", "api_title": "Connections API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"202": "Test delivery enqueued.", "404": "Not found.", "400": "Validation Error: Return fields with errors."}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "openapi:trigger-inbox.yaml", "kind": "openapi", "key": "trigger-inbox.yaml", "title": "Trigger Inbox API (trigger-inbox.yaml)", "summary": "Manage trigger inboxes and their messages — create, pause, resume, and delete inboxes; list, lease, and acknowledge messages.", "body": "openapi: 3.1.0\ninfo:\n title: Trigger Inbox API\n description: Manage trigger inboxes and their messages — create, pause, resume,\n and delete inboxes; list, lease, and acknowledge messages.\n version: 1.0.0\n contact:\n url: https://docs.zapier.com\nservers:\n - url: https://api.zapier.com\n description: Production\ntags:\n - name: Inbox Messages\n description: Lease, acknowledge, and release inbox messages\n - name: Inboxes\n description: Create and manage trigger inboxes\nsecurity:\n - OAuth: []\npaths:\n /trigger-inbox/v1/inboxes:\n get:\n operationId: listTriggerInboxes\n description: List all inboxes for the authenticated user.\n summary: List all inboxes\n parameters:\n - in: query\n name: key\n schema:\n type: string\n - name: limit\n required: false\n in: query\n description: Number of results to return per page.\n schema:\n type: integer\n - in: query\n name: name\n schema:\n type: string\n deprecated: true\n - name: offset\n required: false\n in: query\n description: The initial index from which to return the results.\n schema:\n type: integer\n - in: query\n name: status\n schema:\n type: string\n enum:\n - active\n - deleting\n - initialization_failure\n - initializing\n - paused\n description: '* `initializing` - initializing\n\n * `active` - active\n\n * `paused` - paused\n\n * `deleting` - deleting\n\n * `initialization_failure` - initialization_failure'\n tags:\n - Inboxes\n security:\n - OAuth:\n - external\n responses:\n '200':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/PaginatedInboxList'\n description: 'An inbox: a durable, user-scoped queue for a trigger subscription,\n\n identified by its natural `key`.'\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '400':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: 'Validation Error: Return fields with errors.'\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '429':\n headers:\n Retry-After:\n $ref: '#/components/headers/Retry-After'\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: Too many requests.\n x-zapier-collection-response-exempt: true\n post:\n operationId: createTriggerInbox\n description: Create a new inbox. If a key is provided and an inbox with that\n key already exists for this user, returns 409 Conflict. name remains accepted\n as a deprecated alias for key. Use PUT for idempotent get-or-create semantics.\n summary: Create an inbox\n parameters:\n - in: header\n name: Zapier-Causation-Id\n schema:\n type: string\n description: Optional UUID identifying the event or action that caused this\n request.\n - in: header\n name: Zapier-Correlation-Id\n schema:\n type: string\n description: Optional UUID to trace this request through downstream systems.\n tags:\n - Inboxes\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Inbox'\n examples:\n WithKey:\n value:\n key: example_inbox\n subscription:\n app_key: SlackCLIAPI@1.0.0\n action_key: example_action\n connection_id: 029a64f8-ced3-889b-aa1a-9d37bcd59ddb\n inputs:\n channel: C1234567890\n summary: with_key\n WithNameDeprecated:\n value:\n name: example_inbox\n subscription:\n app_key: SlackCLIAPI@1.0.0\n action_key: example_action\n connection_id: 029a64f8-ced3-889b-aa1a-9d37bcd59ddb\n inputs:\n channel: C1234567890\n summary: with_name_deprecated\n description: Uses the deprecated name alias for key.\n WithoutKey:\n value:\n subscription:\n app_key: SlackCLIAPI@1.0.0\n action_key: example_action\n connection_id: 5678\n inputs:\n channel: C1234567890\n summary: without_key\n WithSlugAppKey:\n value:\n key: example_inbox\n subscription:\n app_key: slack\n action_key: example_action\n connection_id: 029a64f8-ced3-889b-aa1a-9d37bcd59ddb\n inputs:\n channel: C1234567890\n summary: Resolve app_key from a slug\n description: A versionless slug is resolved to the latest version;\n the response's subscription.app_key is the fully-versioned form.\n required: true\n security:\n - OAuth:\n - external\n responses:\n '201':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Inbox'\n description: 'An inbox: a durable, user-scoped queue for a trigger subscription,\n\n identified by its natural `key`.'\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '400':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: Validation error, e.g. the app_key could not be resolved to\n a single app (unknown or ambiguous), or a claim input was invalid.\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '409':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: Conflict error when an inbox with the same key already exists\n for the user.\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '429':\n headers:\n Retry-After:\n $ref: '#/components/headers/Retry-After'\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: Too many requests.\n put:\n operationId: ensureTriggerInbox\n description: Idempotently ensure an inbox exists for the provided key. Returns\n the existing inbox if one with the same key and matching configuration already\n exists, or creates a new one. name remains accepted as a deprecated alias\n for key. Returns 409 if an inbox with the same key but different configuration\n exists.\n summary: Ensure an inbox exists\n parameters:\n - in: header\n name: Zapier-Causation-Id\n schema:\n type: string\n description: Optional UUID identifying the event or action that caused this\n request.\n - in: header\n name: Zapier-Correlation-Id\n schema:\n type: string\n description: Optional UUID to trace this request through downstream systems.\n tags:\n - Inboxes\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/InboxEnsure'\n examples:\n EnsureInbox:\n value:\n key: example_inbox\n subscription:\n app_key: SlackCLIAPI@1.0.0\n action_key: example_action\n connection_id: 029a64f8-ced3-889b-aa1a-9d37bcd59ddb\n inputs:\n channel: C1234567890\n summary: ensure_inbox\n required: true\n security:\n - OAuth:\n - external\n responses:\n '201':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Inbox'\n description: 'An inbox: a durable, user-scoped queue for a trigger subscription,\n\n identified by its natural `key`.'\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '200':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Inbox'\n description: 'An inbox: a durable, user-scoped queue for a trigger subscription,\n\n identified by its natural `key`.'\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '400':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: Validation error, e.g. missing required key field (name is\n accepted as a deprecated alias for key), or the app_key could not be resolved\n to a single app (unknown or ambiguous).\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '409':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: Conflict error when an inbox with the same key and a different\n subscription already exists for the user.\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '429':\n headers:\n Retry-After:\n $ref: '#/components/headers/Retry-After'\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: Too many requests.\n /trigger-inbox/v1/inboxes/{id}:\n get:\n operationId: getTriggerInbox\n description: Return the details of an inbox by unique ID.\n summary: Get inbox details\n parameters:\n - in: path\n name: id\n schema:\n type: string\n format: uuid\n required: true\n tags:\n - Inboxes\n security:\n - OAuth:\n - external\n responses:\n '200':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Inbox'\n description: 'An inbox: a durable, user-scoped queue for a trigger subscription,\n\n identified by its natural `key`.'\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '400':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: 'Validation Error: Return fields with errors.'\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '429':\n headers:\n Retry-After:\n $ref: '#/components/headers/Retry-After'\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: Too many requests.\n patch:\n operationId: patchTriggerInbox\n description: Partially update an inbox. Currently only notification_url can\n be updated.\n summary: Update inbox settings\n parameters:\n - in: path\n name: id\n schema:\n type: string\n format: uuid\n required: true\n tags:\n - Inboxes\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/PatchedInboxPatch'\n examples:\n SetNotificationUrl:\n value:\n notification_url: https://example.com/webhook\n summary: set_notification_url\n security:\n - OAuth:\n - external\n responses:\n '200':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Inbox'\n description: 'An inbox: a durable, user-scoped queue for a trigger subscription,\n\n identified by its natural `key`.'\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '400':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: 'Validation Error: Return fields with errors.'\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '429':\n headers:\n Retry-After:\n $ref: '#/components/headers/Retry-After'\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: Too many requests.\n delete:\n operationId: deleteTriggerInbox\n description: Mark an inbox for deletion for the authenticated user.\n summary: Mark an inbox for deletion\n parameters:\n - in: path\n name: id\n schema:\n type: string\n format: uuid\n required: true\n tags:\n - Inboxes\n security:\n - OAuth:\n - external\n responses:\n '202':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Inbox'\n description: 'An inbox: a durable, user-scoped queue for a trigger subscription,\n\n identified by its natural `key`.'\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '409':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: Conflict error when an inbox cannot be marked for deletion.\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '400':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: 'Validation Error: Return fields with errors.'\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '429':\n headers:\n Retry-After:\n $ref: '#/components/headers/Retry-After'\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: Too many requests.\n /trigger-inbox/v1/inboxes/{id}/pause:\n post:\n operationId: pauseTriggerInbox\n description: Pause an inbox for the authenticated user resulting in messages\n collection being temporarily halted.\n summary: Pause an inbox\n parameters:\n - in: path\n name: id\n schema:\n type: string\n format: uuid\n required: true\n tags:\n - Inboxes\n security:\n - OAuth:\n - external\n responses:\n '200':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Inbox'\n description: 'An inbox: a durable, user-scoped queue for a trigger subscription,\n\n identified by its natural `key`.'\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '409':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: Conflict error when an inbox cannot be paused.\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '400':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: 'Validation Error: Return fields with errors.'\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '429':\n headers:\n Retry-After:\n $ref: '#/components/headers/Retry-After'\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: Too many requests.\n /trigger-inbox/v1/inboxes/{id}/resume:\n post:\n operationId: resumeTriggerInbox\n description: Resume an inbox for the authenticated user resulting in messages\n collection being resumed.\n summary: Resume an inbox\n parameters:\n - in: path\n name: id\n schema:\n type: string\n format: uuid\n required: true\n tags:\n - Inboxes\n security:\n - OAuth:\n - external\n responses:\n '200':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Inbox'\n description: 'An inbox: a durable, user-scoped queue for a trigger subscription,\n\n identified by its natural `key`.'\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '202':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Inbox'\n description: 'An inbox: a durable, user-scoped queue for a trigger subscription,\n\n identified by its natural `key`.'\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '409':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: Conflict error when an inbox cannot be resumed.\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '400':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: 'Validation Error: Return fields with errors.'\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '429':\n headers:\n Retry-After:\n $ref: '#/components/headers/Retry-After'\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: Too many requests.\n /trigger-inbox/v1/inboxes/{inbox_id}/events:\n get:\n operationId: getTriggerInboxEvents\n tags:\n - Inboxes\n summary: Subscribe to inbox notifications over SSE\n description: 'Opens a Server-Sent Events stream that emits one frame per batch\n of newly-available messages on the inbox. The connection stays open until\n the JWT expires, at which point the server closes it.\n\n\n Two kinds of frames are emitted:\n\n\n - **Data frames** (`data: {...}\\n\\n`) signal availability only, they do not\n include message content. Consumers should call the lease endpoint to retrieve\n messages. The JSON payload is described by the response schema below.\n\n - **Heartbeat frames** (`: keep-alive\\n\\n`) are SSE comment lines sent when\n no notification has arrived within the heartbeat interval. They are ignored\n by EventSource clients and exist only to keep intermediaries from closing\n the connection as idle.'\n security:\n - OAuth:\n - external\n parameters:\n - name: inbox_id\n in: path\n required: true\n schema:\n type: string\n format: uuid\n description: The unique identifier of the inbox to subscribe to.\n responses:\n '200':\n description: SSE stream opened. The response body is an open-ended sequence\n of `text/event-stream` frames.\n content:\n text/event-stream:\n schema:\n type: object\n description: JSON payload carried by each `data:` frame. Heartbeat\n frames carry no payload.\n properties:\n inbox_id:\n type: string\n format: uuid\n description: The unique identifier of the inbox that has new messages.\n count:\n type: integer\n minimum: 1\n description: The number of notifications coalesced into this frame.\n required:\n - inbox_id\n - count\n '401':\n description: Missing or invalid JWT in the Authorization header.\n '404':\n description: No inbox with the given id is visible to the authenticated\n user.\n '503':\n description: The notification backend was not reachable in time. Clients\n should retry.\n /trigger-inbox/v1/inboxes/{inbox_id}/messages:\n get:\n operationId: listTriggerInboxMessages\n description: List messages from an inbox for the authenticated user.\n summary: List messages from an inbox\n parameters:\n - name: cursor\n required: false\n in: query\n description: The pagination cursor value.\n schema:\n type: string\n - in: path\n name: inbox_id\n schema:\n type: string\n format: uuid\n required: true\n tags:\n - Inbox Messages\n security:\n - OAuth:\n - external\n responses:\n '200':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/PaginatedMessageList'\n description: ''\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '400':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: 'Validation Error: Return fields with errors.'\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '429':\n headers:\n Retry-After:\n $ref: '#/components/headers/Retry-After'\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: Too many requests.\n x-zapier-collection-response-exempt: true\n /trigger-inbox/v1/inboxes/{inbox_id}/messages/lease:\n post:\n operationId: leaseTriggerInboxMessages\n description: Lease messages from an inbox for the authenticated user.\n summary: Lease messages from an inbox\n parameters:\n - in: path\n name: inbox_id\n schema:\n type: string\n format: uuid\n required: true\n tags:\n - Inbox Messages\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/LeaseRequest'\n examples:\n LeaseMessage:\n value:\n lease_limit: 1\n summary: lease_message\n description: Lease a single message for 60 seconds.\n LeaseMessages:\n value:\n lease_limit: 10\n lease_seconds: 60\n summary: lease_messages\n description: Lease up to 10 messages for 60 seconds.\n security:\n - OAuth:\n - external\n responses:\n '200':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/LeaseResponse'\n examples:\n LeaseEmpty:\n value:\n lease_id: null\n leased_until: null\n results: []\n inbox_attributes:\n status: active\n paused_reason: null\n summary: lease_empty\n description: An empty lease when no messages are available.\n description: Response for a message lease request to an inbox.\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '201':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/LeaseResponse'\n examples:\n LeaseMessages:\n value:\n lease_id: 019ce2fe-5ed1-7318-8a60-33dffd911f6a\n leased_until: '2026-03-12T17:00:47.185Z'\n results:\n - id: 019ce2fe-5ed1-7318-8a60-33dffd911f6b\n created_at: '2026-03-12T16:59:47.185Z'\n status: leased\n payload:\n key: value\n message_attributes:\n lease_count: 1\n error_message: null\n possible_duplicate_data: false\n inbox_attributes:\n status: active\n paused_reason: null\n summary: lease_messages\n description: Lease a single message for 60 seconds.\n LeaseMessagesWithError:\n value:\n lease_id: 019ce2fe-5ed1-7318-8a60-33dffd911f6a\n leased_until: '2026-03-12T17:00:47.185Z'\n results:\n - id: 019ce2fe-5ed1-7318-8a60-33dffd911f6b\n created_at: '2026-03-12T16:59:47.185Z'\n status: leased\n payload:\n key: value\n message_attributes:\n lease_count: 1\n error_message: 'Error while hydrating data from Slack (1.24.0):\n Your Slack account on Zapier is expired/invalid. Please\n reconnect it to fix this.'\n possible_duplicate_data: false\n inbox_attributes:\n status: active\n paused_reason: null\n summary: lease_messages_with_error\n description: Lease a message from a batch that had a hydration error.\n LeaseMessagesWithPossibleDuplicates:\n value:\n lease_id: 019ce2fe-5ed1-7318-8a60-33dffd911f6a\n leased_until: '2026-03-12T17:00:47.185Z'\n results:\n - id: 019ce2fe-5ed1-7318-8a60-33dffd911f6b\n created_at: '2026-03-12T16:59:47.185Z'\n status: leased\n payload:\n key: value\n message_attributes:\n lease_count: 1\n error_message: null\n possible_duplicate_data: true\n inbox_attributes:\n status: active\n paused_reason: null\n summary: lease_messages_with_possible_duplicates\n description: Lease a message that may contain duplicate data due\n to a dedupe key change.\n description: Response for a message lease request to an inbox.\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '409':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/LeaseConflictResponse'\n examples:\n LeaseConflict:\n value:\n detail: Inbox is paused and fully drained.\n inbox_attributes:\n status: paused\n paused_reason: authentication\n paused_at: '2026-03-12T16:59:47.185Z'\n summary: lease_conflict\n description: Inbox is paused and fully drained — no more messages.\n description: Response when leasing from a paused and fully drained inbox.\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '400':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: 'Validation Error: Return fields with errors.'\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '429':\n headers:\n Retry-After:\n $ref: '#/components/headers/Retry-After'\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: Too many requests.\n /trigger-inbox/v1/inboxes/{inbox_id}/messages/ack:\n post:\n operationId: acknowledgeTriggerInboxMessages\n description: Acknowledge messages from an inbox for the authenticated user.\n summary: Acknowledge messages from an inbox\n parameters:\n - in: path\n name: inbox_id\n schema:\n type: string\n format: uuid\n required: true\n tags:\n - Inbox Messages\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/AckRequest'\n examples:\n Ack:\n value:\n lease_id: 019ce2fe-5ed1-7318-8a60-33dffd911f6a\n summary: ack\n description: Acknowledge an entire lease.\n AckMessageIds:\n value:\n lease_id: 019ce2fe-5ed1-7318-8a60-33dffd911f6a\n message_ids:\n - 019ce303-cf30-7efb-aa91-89488a407dc2\n summary: ack_message_ids\n description: Acknowledge specific messages within a lease.\n required: true\n security:\n - OAuth:\n - external\n responses:\n '200':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/AckResponse'\n examples:\n AckEmpty:\n value:\n acked_id: null\n results: []\n summary: ack_empty\n description: An empty acknowledgment when no messages are acknowledged.\n description: Response for a message acknowledge request to an inbox.\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '201':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/AckResponse'\n examples:\n AckMessages:\n value:\n acked_id: 019ce305-35be-764b-bcae-70ba567b7357\n results:\n - id: 019ce2fe-5ed1-7318-8a60-33dffd911f6b\n created_at: '2026-03-12T16:59:47.185Z'\n status: acked\n message_attributes:\n lease_count: 1\n error_message: null\n possible_duplicate_data: false\n summary: ack_messages\n description: Acknowledgement of leased messages.\n description: Response for a message acknowledge request to an inbox.\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '400':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: 'Validation Error: Return fields with errors.'\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '429':\n headers:\n Retry-After:\n $ref: '#/components/headers/Retry-After'\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: Too many requests.\n /trigger-inbox/v1/inboxes/{inbox_id}/messages/release:\n post:\n operationId: releaseTriggerInboxMessages\n description: Release the lease on one or more leased messages without acknowledging\n them. The messages become immediately available for leasing again. The original\n lease still counts against the per-message lease limit; releasing does not\n refund the attempt.\n summary: Release leased messages without acknowledging\n parameters:\n - in: path\n name: inbox_id\n schema:\n type: string\n format: uuid\n required: true\n tags:\n - Inbox Messages\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ReleaseRequest'\n examples:\n Release:\n value:\n lease_id: 019ce2fe-5ed1-7318-8a60-33dffd911f6a\n summary: release\n description: Release every message held under a lease.\n ReleaseMessageIds:\n value:\n lease_id: 019ce2fe-5ed1-7318-8a60-33dffd911f6a\n message_ids:\n - 019ce303-cf30-7efb-aa91-89488a407dc2\n summary: release_message_ids\n description: Release specific messages within a lease.\n required: true\n security:\n - OAuth:\n - external\n responses:\n '200':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ReleaseResponse'\n examples:\n ReleaseEmpty:\n value:\n released_id: null\n results: []\n summary: release_empty\n description: An empty release when no messages match the lease.\n description: Response for a message release request to an inbox.\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '201':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ReleaseResponse'\n examples:\n ReleaseMessages:\n value:\n released_id: 019ce305-35be-764b-bcae-70ba567b7357\n results:\n - id: 019ce2fe-5ed1-7318-8a60-33dffd911f6b\n created_at: '2026-03-12T16:59:47.185Z'\n status: available\n message_attributes:\n lease_count: 1\n error_message: null\n possible_duplicate_data: false\n summary: release_messages\n description: Release of leased messages.\n description: Response for a message release request to an inbox.\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '400':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: 'Validation Error: Return fields with errors.'\n headers:\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n '429':\n headers:\n Retry-After:\n $ref: '#/components/headers/Retry-After'\n X-RateLimit-Limit:\n $ref: '#/components/headers/X-RateLimit-Limit'\n X-RateLimit-Remaining:\n $ref: '#/components/headers/X-RateLimit-Remaining'\n X-RateLimit-Reset:\n $ref: '#/components/headers/X-RateLimit-Reset'\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Errors'\n description: Too many requests.\ncomponents:\n headers:\n Retry-After:\n schema:\n type: number\n description: The number of seconds to wait before making a new request.\n required: true\n X-RateLimit-Limit:\n schema:\n type: string\n description: The rate limit ceiling for that given request.\n required: true\n X-RateLimit-Remaining:\n schema:\n type: string\n description: The number of requests left for the window.\n required: true\n X-RateLimit-Reset:\n schema:\n type: string\n description: The time at which the current rate limit window resets in seconds.\n required: true\n schemas:\n AckRequest:\n type: object\n description: Request to acknowledge a leased message from an inbox.\n properties:\n lease_id:\n type: string\n format: uuid\n description: The unique identifier for the lease.\n message_ids:\n type: array\n items:\n type: string\n format: uuid\n description: The list of message IDs to acknowledge. If not specified all\n messages matching the lease_id will be acknowledged.\n maxItems: 100\n minItems: 1\n required:\n - lease_id\n AckResponse:\n type: object\n description: Response for a message acknowledge request to an inbox.\n properties:\n acked_id:\n type:\n - string\n - 'null'\n format: uuid\n description: The unique identifier for the acknowledged messages.\n results:\n type: array\n items:\n $ref: '#/components/schemas/Message'\n description: The list of messages acknowledged.\n required:\n - acked_id\n - results\n BlankEnum:\n enum:\n - ''\n ErrorDetail:\n type: object\n description: 'Per the schema defined in the engineering index.\n\n\n https://engineering.zapier.com/guides/api-design-guidelines/error-handling/'\n properties:\n code:\n type: string\n description: A unique identifier for this particular occurrence of the problem.\n detail:\n type: string\n description: A human-readable explanation specific to this occurrence of\n the problem.\n status:\n type: integer\n description: HTTP status code for that error.\n title:\n type: string\n description: A short summary of the problem.\n source:\n type: object\n additionalProperties: {}\n description: An object containing references to the primary source of the\n error.\n required:\n - code\n - detail\n Errors:\n type: object\n properties:\n errors:\n type: array\n items:\n $ref: '#/components/schemas/ErrorDetail'\n description: An array of error objects.\n required:\n - errors\n Inbox:\n type: object\n description: 'An inbox: a durable, user-scoped queue for a trigger subscription,\n\n identified by its natural `key`.'\n properties:\n id:\n type: string\n format: uuid\n readOnly: true\n description: The unique identifier for the inbox.\n created_at:\n type: string\n format: date-time\n readOnly: true\n description: Creation timestamp in ISO 8601 format.\n key:\n type: string\n description: The inbox's natural key. Set at creation, immutable, unique\n per user.\n maxLength: 100\n name:\n type: string\n maxLength: 100\n deprecated: true\n description: Deprecated alias for `key`. Use `key` instead.\n status:\n type: string\n readOnly: true\n description: The status of the inbox.\n paused_reason:\n description: 'The reason the inbox was paused, if applicable.\n\n\n * `user` - user\n\n * `authentication` - authentication\n\n * `authentication_access_revoked` - authentication_access_revoked\n\n * `partner_revoked` - partner_revoked\n\n * `subscribe_failed` - subscribe_failed\n\n * `migrate_failed` - migrate_failed\n\n * `abandoned` - abandoned\n\n * `unknown` - unknown\n\n * `upstream_failures` - upstream_failures'\n oneOf:\n - $ref: '#/components/schemas/PausedReasonEnum'\n - $ref: '#/components/schemas/BlankEnum'\n - $ref: '#/components/schemas/NullEnum'\n notification_url:\n type:\n - string\n - 'null'\n format: uri\n description: URL to POST notifications to when messages become available.\n maxLength: 2048\n subscription:\n $ref: '#/components/schemas/TriggerSubscription'\n required:\n - created_at\n - id\n - status\n - subscription\n InboxAttributes:\n type: object\n description: Inbox state surfaced alongside lease responses.\n properties:\n status:\n type: string\n readOnly: true\n description: The current status of the inbox.\n paused_reason:\n readOnly: true\n description: 'The reason the inbox was paused, if applicable.\n\n\n * `user` - user\n\n * `authentication` - authentication\n\n * `authentication_access_revoked` - authentication_access_revoked\n\n * `partner_revoked` - partner_revoked\n\n * `subscribe_failed` - subscribe_failed\n\n * `migrate_failed` - migrate_failed\n\n * `abandoned` - abandoned\n\n * `unknown` - unknown\n\n * `upstream_failures` - upstream_failures'\n oneOf:\n - $ref: '#/components/schemas/PausedReasonEnum'\n - $ref: '#/components/schemas/NullEnum'\n required:\n - paused_reason\n - status\n InboxEnsure:\n type: object\n description: 'Request to idempotently ensure an inbox exists. A `key` is required\n\n (`name` is accepted as a deprecated alias).'\n properties:\n id:\n type: string\n format: uuid\n readOnly: true\n description: The unique identifier for the inbox.\n created_at:\n type: string\n format: date-time\n readOnly: true\n description: Creation timestamp in ISO 8601 format.\n key:\n type: string\n description: The inbox's natural key. Set at creation, immutable, unique\n per user.\n maxLength: 100\n name:\n type: string\n maxLength: 100\n deprecated: true\n description: Deprecated alias for `key`. Use `key` instead.\n status:\n type: string\n readOnly: true\n description: The status of the inbox.\n paused_reason:\n description: 'The reason the inbox was paused, if applicable.\n\n\n * `user` - user\n\n * `authentication` - authentication\n\n * `authentication_access_revoked` - authentication_access_revoked\n\n * `partner_revoked` - partner_revoked\n\n * `subscribe_failed` - subscribe_failed\n\n * `migrate_failed` - migrate_failed\n\n * `abandoned` - abandoned\n\n * `unknown` - unknown\n\n * `upstream_failures` - upstream_failures'\n oneOf:\n - $ref: '#/components/schemas/PausedReasonEnum'\n - $ref: '#/components/schemas/BlankEnum'\n - $ref: '#/components/schemas/NullEnum'\n notification_url:\n type:\n - string\n - 'null'\n format: uri\n description: URL to POST notifications to when messages become available.\n maxLength: 2048\n subscription:\n $ref: '#/components/schemas/TriggerSubscription'\n required:\n - created_at\n - id\n - status\n - subscription\n LeaseConflictAttributes:\n type: object\n description: Inbox attributes included in a 409 conflict response, with paused_at.\n properties:\n status:\n type: string\n readOnly: true\n description: The current status of the inbox.\n paused_reason:\n readOnly: true\n description: 'The reason the inbox was paused, if applicable.\n\n\n * `user` - user\n\n * `authentication` - authentication\n\n * `authentication_access_revoked` - authentication_access_revoked\n\n * `partner_revoked` - partner_revoked\n\n * `subscribe_failed` - subscribe_failed\n\n * `migrate_failed` - migrate_failed\n\n * `abandoned` - abandoned\n\n * `unknown` - unknown\n\n * `upstream_failures` - upstream_failures'\n oneOf:\n - $ref: '#/components/schemas/PausedReasonEnum'\n - $ref: '#/components/schemas/NullEnum'\n paused_at:\n type:\n - string\n - 'null'\n format: date-time\n readOnly: true\n description: When the inbox was paused, in ISO 8601 format.\n required:\n - paused_at\n - paused_reason\n - status\n LeaseConflictResponse:\n type: object\n description: Response when leasing from a paused and fully drained inbox.\n properties:\n detail:\n type: string\n readOnly: true\n description: A human-readable explanation of why the lease was rejected.\n inbox_attributes:\n allOf:\n - $ref: '#/components/schemas/LeaseConflictAttributes'\n readOnly: true\n description: Current inbox state including pause details.\n required:\n - detail\n - inbox_attributes\n LeaseRequest:\n type: object\n description: Request to lease message from an inbox.\n properties:\n lease_seconds:\n type: integer\n maximum: 3600\n minimum: 1\n default: 300\n description: The number of seconds to lease the message for.\n lease_limit:\n type: integer\n maximum: 100\n minimum: 1\n default: 10\n description: The number of messages to lease.\n LeaseResponse:\n type: object\n description: Response for a message lease request to an inbox.\n properties:\n lease_id:\n type:\n - string\n - 'null'\n format: uuid\n description: The unique identifier for the lease.\n leased_until:\n type:\n - string\n - 'null'\n format: date-time\n description: The timestamp until which the messages are leased in ISO 8601\n format.\n results:\n type: array\n items:\n $ref: '#/components/schemas/LeasedMessage'\n description: The list of messages leased.\n inbox_attributes:\n allOf:\n - $ref: '#/components/schemas/InboxAttributes'\n readOnly: true\n description: Current inbox state surfaced alongside the lease.\n required:\n - inbox_attributes\n - lease_id\n - leased_until\n - results\n LeasedMessage:\n type: object\n properties:\n id:\n type: string\n format: uuid\n readOnly: true\n description: The unique identifier for the message.\n created_at:\n type: string\n format: date-time\n readOnly: true\n description: Creation timestamp in ISO 8601 format.\n status:\n allOf:\n - $ref: '#/components/schemas/StatusEnum'\n description: The status of the message.\n readOnly: true\n message_attributes:\n allOf:\n - $ref: '#/components/schemas/MessageAttributes'\n readOnly: true\n description: Attributes associated with the message, such as lease count\n and error information.\n payload:\n type: object\n additionalProperties: {}\n description: The payload of the message.\n readOnly: true\n required:\n - created_at\n - id\n - message_attributes\n - payload\n - status\n Message:\n type: object\n properties:\n id:\n type: string\n format: uuid\n readOnly: true\n description: The unique identifier for the message.\n created_at:\n type: string\n format: date-time\n readOnly: true\n description: Creation timestamp in ISO 8601 format.\n status:\n allOf:\n - $ref: '#/components/schemas/StatusEnum'\n description: The status of the message.\n readOnly: true\n message_attributes:\n allOf:\n - $ref: '#/components/schemas/MessageAttributes'\n readOnly: true\n description: Attributes associated with the message, such as lease count\n and error information.\n required:\n - created_at\n - id\n - message_attributes\n - status\n MessageAttributes:\n type: object\n properties:\n lease_count:\n type: integer\n readOnly: true\n description: Number of times this message has been leased.\n error_message:\n type:\n - string\n - 'null'\n readOnly: true\n description: Error message from the batch that produced this message, if\n any.\n possible_duplicate_data:\n type: boolean\n readOnly: true\n description: True when the message may contain duplicate data due to a change\n in the deduplication key. Consumers should treat this data with caution\n and may want to apply their own deduplication logic.\n required:\n - error_message\n - lease_count\n - possible_duplicate_data\n NullEnum:\n type: 'null'\n PaginatedInboxList:\n type: object\n required:\n - count\n - results\n properties:\n count:\n type: integer\n description: Total number of results across all pages.\n example: 123\n next:\n type: string\n description: Link to next page of results if any.\n nullable: true\n format: uri\n example: https://api.example.org/accounts/?offset=400&limit=100\n previous:\n type: string\n description: Link to previous page of results if any.\n nullable: true\n format: uri\n example: https://api.example.org/accounts/?offset=200&limit=100\n results:\n description: Array of results for the current page.\n type: array\n items:\n $ref: '#/components/schemas/Inbox'\n PaginatedMessageList:\n type: object\n required:\n - next\n - previous\n - results\n properties:\n next:\n type: string\n description: Link to next page of results if any.\n nullable: true\n format: uri\n example: https://api.example.org/accounts/?cursor=cD00ODY%3D\n previous:\n type: string\n description: Link to previous page of results if any.\n nullable: true\n format: uri\n example: https://api.example.org/accounts/?cursor=cj0xJnA9NDg3\n results:\n description: Array of results for the current page.\n type: array\n items:\n $ref: '#/components/schemas/Message'\n PatchedInboxPatch:\n type: object\n properties:\n notification_url:\n type:\n - string\n - 'null'\n format: uri\n description: URL to POST notifications to when messages become available.\n maxLength: 2048\n PausedReasonEnum:\n enum:\n - user\n - authentication\n - authentication_access_revoked\n - partner_revoked\n - subscribe_failed\n - migrate_failed\n - abandoned\n - unknown\n - upstream_failures\n type: string\n description: '* `user` - user\n\n * `authentication` - authentication\n\n * `authentication_access_revoked` - authentication_access_revoked\n\n * `partner_revoked` - partner_revoked\n\n * `subscribe_failed` - subscribe_failed\n\n * `migrate_failed` - migrate_failed\n\n * `abandoned` - abandoned\n\n * `unknown` - unknown\n\n * `upstream_failures` - upstream_failures'\n ReleaseRequest:\n type: object\n description: Request to release a leased message back to the inbox without acknowledging\n it.\n properties:\n lease_id:\n type: string\n format: uuid\n description: The unique identifier for the lease.\n message_ids:\n type: array\n items:\n type: string\n format: uuid\n description: The list of message IDs to release. If not specified all messages\n matching the lease_id will be released.\n maxItems: 100\n minItems: 1\n required:\n - lease_id\n ReleaseResponse:\n type: object\n description: Response for a message release request to an inbox.\n properties:\n released_id:\n type:\n - string\n - 'null'\n format: uuid\n description: The unique identifier for the released messages.\n results:\n type: array\n items:\n $ref: '#/components/schemas/Message'\n description: The list of messages whose leases were released.\n required:\n - released_id\n - results\n StatusEnum:\n enum:\n - available\n - leased\n - acked\n - quarantined\n type: string\n TriggerSubscription:\n type: object\n description: Trigger subscription configuration for an inbox.\n properties:\n connection_id:\n oneOf:\n - type: string\n format: uuid\n - type: integer\n format: integer\n - type: 'null'\n description: The ID of the connection associated with this inbox.\n app_key:\n type: string\n description: App identifier. Accepts a fully-versioned selected_api (`SlackCLIAPI@1.0.0`,\n used as-is), a versionless selected_api (`SlackCLIAPI`), the `@latest`\n sentinel (`SlackCLIAPI@latest`), or a service slug (`slack`). Versionless,\n `@latest`, and slug forms are resolved to the latest published version\n at creation time; the inbox always stores and returns the fully-versioned\n form. Returns 400 if the identifier matches no app or is ambiguous (matches\n more than one).\n action_key:\n type: string\n description: The key of the app action associated with this inbox.\n inputs:\n type: object\n additionalProperties: {}\n description: The inputs provided to the app action associated with this\n inbox.\n required:\n - action_key\n - app_key\n - inputs\n securitySchemes:\n OAuth:\n type: oauth2\n description: OAuth 2.0 authentication.\n flows:\n authorizationCode:\n authorizationUrl: https://zapier.com/oauth/authorize\n tokenUrl: https://zapier.com/oauth/token\n scopes:\n external: Scope that gives access to all Public APIs\n clientCredentials:\n tokenUrl: https://zapier.com/oauth/token\n scopes:\n external: Scope that gives access to all Public APIs\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/api-reference/specs/trigger-inbox.yaml", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "openapi"], "related": [], "meta": {"title": "Trigger Inbox API", "version": "1.0.0", "servers": ["https://api.zapier.com"], "path_count": 9}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:listtriggerinboxes", "kind": "api_function", "key": "listTriggerInboxes", "title": "GET /trigger-inbox/v1/inboxes — List all inboxes", "summary": "List all inboxes", "body": "# `listTriggerInboxes`\n\n> List all inboxes\n\n## High-level description\n\nList all inboxes for the authenticated user.\n\n## Internals\n\n`GET https://api.zapier.com/trigger-inbox/v1/inboxes` from **Trigger Inbox API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n key?: string; // in query — \n limit?: integer; // in query — Number of results to return per page.\n name?: string; // in query — \n offset?: integer; // in query — The initial index from which to return the results.\n status?: string; // in query — * `initializing` - initializing\n* `active` - active\n* `paused` - paused\n* `deleting` - deleting\n* `i\n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"An inbox: a durable, user-scoped queue for a trigger subscription,\\nidentified by its natural `key`.\",\n \"400\": \"Validation Error: Return fields with errors.\",\n \"429\": \"Too many requests.\"\n}\n```\n\n- Tags: Inboxes\n- Security: [{\"OAuth\": [\"external\"]}]\n\n## Example\n\n```http\nGET /trigger-inbox/v1/inboxes HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "GET /trigger-inbox/v1/inboxes", "signature": "GET /trigger-inbox/v1/inboxes", "aliases": [], "flags": [], "args": [{"name": "key", "in": "query", "required": false, "type": "string", "description": ""}, {"name": "limit", "in": "query", "required": false, "type": "integer", "description": "Number of results to return per page."}, {"name": "name", "in": "query", "required": false, "type": "string", "description": ""}, {"name": "offset", "in": "query", "required": false, "type": "integer", "description": "The initial index from which to return the results."}, {"name": "status", "in": "query", "required": false, "type": "string", "description": "* `initializing` - initializing\n* `active` - active\n* `paused` - paused\n* `deleting` - deleting\n* `initialization_failure` - initialization_failure"}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "inboxes", "openapi"], "related": [], "meta": {"method": "GET", "path": "/trigger-inbox/v1/inboxes", "spec": "trigger-inbox.yaml", "api_title": "Trigger Inbox API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"200": "An inbox: a durable, user-scoped queue for a trigger subscription,\nidentified by its natural `key`.", "400": "Validation Error: Return fields with errors.", "429": "Too many requests."}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:createtriggerinbox", "kind": "api_function", "key": "createTriggerInbox", "title": "POST /trigger-inbox/v1/inboxes — Create an inbox", "summary": "Create an inbox", "body": "# `createTriggerInbox`\n\n> Create an inbox\n\n## High-level description\n\nCreate a new inbox. If a key is provided and an inbox with that key already exists for this user, returns 409 Conflict. name remains accepted as a deprecated alias for key. Use PUT for idempotent get-or-create semantics.\n\n## Internals\n\n`POST https://api.zapier.com/trigger-inbox/v1/inboxes` from **Trigger Inbox API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n Zapier-Causation-Id?: string; // in header — Optional UUID identifying the event or action that caused this request.\n Zapier-Correlation-Id?: string; // in header — Optional UUID to trace this request through downstream systems.\n body?: Inbox; // request JSON\n};\n```\n\n## Outputs\n\n```json\n{\n \"201\": \"An inbox: a durable, user-scoped queue for a trigger subscription,\\nidentified by its natural `key`.\",\n \"400\": \"Validation error, e.g. the app_key could not be resolved to a single app (unknown or ambiguous), or a claim input was invalid.\",\n \"409\": \"Conflict error when an inbox with the same key already exists for the user.\",\n \"429\": \"Too many requests.\"\n}\n```\n\n- Tags: Inboxes\n- Security: [{\"OAuth\": [\"external\"]}]\n\n## Example\n\n```http\nPOST /trigger-inbox/v1/inboxes HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "POST /trigger-inbox/v1/inboxes", "signature": "POST /trigger-inbox/v1/inboxes", "aliases": [], "flags": [], "args": [{"name": "Zapier-Causation-Id", "in": "header", "required": false, "type": "string", "description": "Optional UUID identifying the event or action that caused this request."}, {"name": "Zapier-Correlation-Id", "in": "header", "required": false, "type": "string", "description": "Optional UUID to trace this request through downstream systems."}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "inboxes", "openapi"], "related": [], "meta": {"method": "POST", "path": "/trigger-inbox/v1/inboxes", "spec": "trigger-inbox.yaml", "api_title": "Trigger Inbox API", "servers": ["https://api.zapier.com"], "request_schema": {"$ref": "#/components/schemas/Inbox"}, "responses": {"201": "An inbox: a durable, user-scoped queue for a trigger subscription,\nidentified by its natural `key`.", "400": "Validation error, e.g. the app_key could not be resolved to a single app (unknown or ambiguous), or a claim input was invalid.", "409": "Conflict error when an inbox with the same key already exists for the user.", "429": "Too many requests."}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:ensuretriggerinbox", "kind": "api_function", "key": "ensureTriggerInbox", "title": "PUT /trigger-inbox/v1/inboxes — Ensure an inbox exists", "summary": "Ensure an inbox exists", "body": "# `ensureTriggerInbox`\n\n> Ensure an inbox exists\n\n## High-level description\n\nIdempotently ensure an inbox exists for the provided key. Returns the existing inbox if one with the same key and matching configuration already exists, or creates a new one. name remains accepted as a deprecated alias for key. Returns 409 if an inbox with the same key but different configuration exists.\n\n## Internals\n\n`PUT https://api.zapier.com/trigger-inbox/v1/inboxes` from **Trigger Inbox API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n Zapier-Causation-Id?: string; // in header — Optional UUID identifying the event or action that caused this request.\n Zapier-Correlation-Id?: string; // in header — Optional UUID to trace this request through downstream systems.\n body?: InboxEnsure; // request JSON\n};\n```\n\n## Outputs\n\n```json\n{\n \"201\": \"An inbox: a durable, user-scoped queue for a trigger subscription,\\nidentified by its natural `key`.\",\n \"200\": \"An inbox: a durable, user-scoped queue for a trigger subscription,\\nidentified by its natural `key`.\",\n \"400\": \"Validation error, e.g. missing required key field (name is accepted as a deprecated alias for key), or the app_key could not be resolved to a single app (unknown or ambiguous).\",\n \"409\": \"Conflict error when an inbox with the same key and a different subscription already exists for the user.\",\n \"429\": \"Too many requests.\"\n}\n```\n\n- Tags: Inboxes\n- Security: [{\"OAuth\": [\"external\"]}]\n\n## Example\n\n```http\nPUT /trigger-inbox/v1/inboxes HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "PUT /trigger-inbox/v1/inboxes", "signature": "PUT /trigger-inbox/v1/inboxes", "aliases": [], "flags": [], "args": [{"name": "Zapier-Causation-Id", "in": "header", "required": false, "type": "string", "description": "Optional UUID identifying the event or action that caused this request."}, {"name": "Zapier-Correlation-Id", "in": "header", "required": false, "type": "string", "description": "Optional UUID to trace this request through downstream systems."}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "inboxes", "openapi"], "related": [], "meta": {"method": "PUT", "path": "/trigger-inbox/v1/inboxes", "spec": "trigger-inbox.yaml", "api_title": "Trigger Inbox API", "servers": ["https://api.zapier.com"], "request_schema": {"$ref": "#/components/schemas/InboxEnsure"}, "responses": {"201": "An inbox: a durable, user-scoped queue for a trigger subscription,\nidentified by its natural `key`.", "200": "An inbox: a durable, user-scoped queue for a trigger subscription,\nidentified by its natural `key`.", "400": "Validation error, e.g. missing required key field (name is accepted as a deprecated alias for key), or the app_key could not be resolved to a single app (unknown or ambiguous).", "409": "Conflict error when an inbox with the same key and a different subscription already exists for the user.", "429": "Too many requests."}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:gettriggerinbox", "kind": "api_function", "key": "getTriggerInbox", "title": "GET /trigger-inbox/v1/inboxes/{id} — Get inbox details", "summary": "Get inbox details", "body": "# `getTriggerInbox`\n\n> Get inbox details\n\n## High-level description\n\nReturn the details of an inbox by unique ID.\n\n## Internals\n\n`GET https://api.zapier.com/trigger-inbox/v1/inboxes/{id}` from **Trigger Inbox API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n id: string; // in path — \n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"An inbox: a durable, user-scoped queue for a trigger subscription,\\nidentified by its natural `key`.\",\n \"400\": \"Validation Error: Return fields with errors.\",\n \"429\": \"Too many requests.\"\n}\n```\n\n- Tags: Inboxes\n- Security: [{\"OAuth\": [\"external\"]}]\n\n## Example\n\n```http\nGET /trigger-inbox/v1/inboxes/{id} HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "GET /trigger-inbox/v1/inboxes/{id}", "signature": "GET /trigger-inbox/v1/inboxes/{id}", "aliases": [], "flags": [], "args": [{"name": "id", "in": "path", "required": true, "type": "string", "description": ""}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "inboxes", "openapi"], "related": [], "meta": {"method": "GET", "path": "/trigger-inbox/v1/inboxes/{id}", "spec": "trigger-inbox.yaml", "api_title": "Trigger Inbox API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"200": "An inbox: a durable, user-scoped queue for a trigger subscription,\nidentified by its natural `key`.", "400": "Validation Error: Return fields with errors.", "429": "Too many requests."}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:patchtriggerinbox", "kind": "api_function", "key": "patchTriggerInbox", "title": "PATCH /trigger-inbox/v1/inboxes/{id} — Update inbox settings", "summary": "Update inbox settings", "body": "# `patchTriggerInbox`\n\n> Update inbox settings\n\n## High-level description\n\nPartially update an inbox. Currently only notification_url can be updated.\n\n## Internals\n\n`PATCH https://api.zapier.com/trigger-inbox/v1/inboxes/{id}` from **Trigger Inbox API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n id: string; // in path — \n body?: PatchedInboxPatch; // request JSON\n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"An inbox: a durable, user-scoped queue for a trigger subscription,\\nidentified by its natural `key`.\",\n \"400\": \"Validation Error: Return fields with errors.\",\n \"429\": \"Too many requests.\"\n}\n```\n\n- Tags: Inboxes\n- Security: [{\"OAuth\": [\"external\"]}]\n\n## Example\n\n```http\nPATCH /trigger-inbox/v1/inboxes/{id} HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "PATCH /trigger-inbox/v1/inboxes/{id}", "signature": "PATCH /trigger-inbox/v1/inboxes/{id}", "aliases": [], "flags": [], "args": [{"name": "id", "in": "path", "required": true, "type": "string", "description": ""}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "inboxes", "openapi"], "related": [], "meta": {"method": "PATCH", "path": "/trigger-inbox/v1/inboxes/{id}", "spec": "trigger-inbox.yaml", "api_title": "Trigger Inbox API", "servers": ["https://api.zapier.com"], "request_schema": {"$ref": "#/components/schemas/PatchedInboxPatch"}, "responses": {"200": "An inbox: a durable, user-scoped queue for a trigger subscription,\nidentified by its natural `key`.", "400": "Validation Error: Return fields with errors.", "429": "Too many requests."}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:deletetriggerinbox", "kind": "api_function", "key": "deleteTriggerInbox", "title": "DELETE /trigger-inbox/v1/inboxes/{id} — Mark an inbox for deletion", "summary": "Mark an inbox for deletion", "body": "# `deleteTriggerInbox`\n\n> Mark an inbox for deletion\n\n## High-level description\n\nMark an inbox for deletion for the authenticated user.\n\n## Internals\n\n`DELETE https://api.zapier.com/trigger-inbox/v1/inboxes/{id}` from **Trigger Inbox API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n id: string; // in path — \n};\n```\n\n## Outputs\n\n```json\n{\n \"202\": \"An inbox: a durable, user-scoped queue for a trigger subscription,\\nidentified by its natural `key`.\",\n \"409\": \"Conflict error when an inbox cannot be marked for deletion.\",\n \"400\": \"Validation Error: Return fields with errors.\",\n \"429\": \"Too many requests.\"\n}\n```\n\n- Tags: Inboxes\n- Security: [{\"OAuth\": [\"external\"]}]\n\n## Example\n\n```http\nDELETE /trigger-inbox/v1/inboxes/{id} HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "DELETE /trigger-inbox/v1/inboxes/{id}", "signature": "DELETE /trigger-inbox/v1/inboxes/{id}", "aliases": [], "flags": [], "args": [{"name": "id", "in": "path", "required": true, "type": "string", "description": ""}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "inboxes", "openapi"], "related": [], "meta": {"method": "DELETE", "path": "/trigger-inbox/v1/inboxes/{id}", "spec": "trigger-inbox.yaml", "api_title": "Trigger Inbox API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"202": "An inbox: a durable, user-scoped queue for a trigger subscription,\nidentified by its natural `key`.", "409": "Conflict error when an inbox cannot be marked for deletion.", "400": "Validation Error: Return fields with errors.", "429": "Too many requests."}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:pausetriggerinbox", "kind": "api_function", "key": "pauseTriggerInbox", "title": "POST /trigger-inbox/v1/inboxes/{id}/pause — Pause an inbox", "summary": "Pause an inbox", "body": "# `pauseTriggerInbox`\n\n> Pause an inbox\n\n## High-level description\n\nPause an inbox for the authenticated user resulting in messages collection being temporarily halted.\n\n## Internals\n\n`POST https://api.zapier.com/trigger-inbox/v1/inboxes/{id}/pause` from **Trigger Inbox API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n id: string; // in path — \n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"An inbox: a durable, user-scoped queue for a trigger subscription,\\nidentified by its natural `key`.\",\n \"409\": \"Conflict error when an inbox cannot be paused.\",\n \"400\": \"Validation Error: Return fields with errors.\",\n \"429\": \"Too many requests.\"\n}\n```\n\n- Tags: Inboxes\n- Security: [{\"OAuth\": [\"external\"]}]\n\n## Example\n\n```http\nPOST /trigger-inbox/v1/inboxes/{id}/pause HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "POST /trigger-inbox/v1/inboxes/{id}/pause", "signature": "POST /trigger-inbox/v1/inboxes/{id}/pause", "aliases": [], "flags": [], "args": [{"name": "id", "in": "path", "required": true, "type": "string", "description": ""}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "inboxes", "openapi"], "related": [], "meta": {"method": "POST", "path": "/trigger-inbox/v1/inboxes/{id}/pause", "spec": "trigger-inbox.yaml", "api_title": "Trigger Inbox API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"200": "An inbox: a durable, user-scoped queue for a trigger subscription,\nidentified by its natural `key`.", "409": "Conflict error when an inbox cannot be paused.", "400": "Validation Error: Return fields with errors.", "429": "Too many requests."}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:resumetriggerinbox", "kind": "api_function", "key": "resumeTriggerInbox", "title": "POST /trigger-inbox/v1/inboxes/{id}/resume — Resume an inbox", "summary": "Resume an inbox", "body": "# `resumeTriggerInbox`\n\n> Resume an inbox\n\n## High-level description\n\nResume an inbox for the authenticated user resulting in messages collection being resumed.\n\n## Internals\n\n`POST https://api.zapier.com/trigger-inbox/v1/inboxes/{id}/resume` from **Trigger Inbox API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n id: string; // in path — \n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"An inbox: a durable, user-scoped queue for a trigger subscription,\\nidentified by its natural `key`.\",\n \"202\": \"An inbox: a durable, user-scoped queue for a trigger subscription,\\nidentified by its natural `key`.\",\n \"409\": \"Conflict error when an inbox cannot be resumed.\",\n \"400\": \"Validation Error: Return fields with errors.\",\n \"429\": \"Too many requests.\"\n}\n```\n\n- Tags: Inboxes\n- Security: [{\"OAuth\": [\"external\"]}]\n\n## Example\n\n```http\nPOST /trigger-inbox/v1/inboxes/{id}/resume HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "POST /trigger-inbox/v1/inboxes/{id}/resume", "signature": "POST /trigger-inbox/v1/inboxes/{id}/resume", "aliases": [], "flags": [], "args": [{"name": "id", "in": "path", "required": true, "type": "string", "description": ""}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "inboxes", "openapi"], "related": [], "meta": {"method": "POST", "path": "/trigger-inbox/v1/inboxes/{id}/resume", "spec": "trigger-inbox.yaml", "api_title": "Trigger Inbox API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"200": "An inbox: a durable, user-scoped queue for a trigger subscription,\nidentified by its natural `key`.", "202": "An inbox: a durable, user-scoped queue for a trigger subscription,\nidentified by its natural `key`.", "409": "Conflict error when an inbox cannot be resumed.", "400": "Validation Error: Return fields with errors.", "429": "Too many requests."}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:gettriggerinboxevents", "kind": "api_function", "key": "getTriggerInboxEvents", "title": "GET /trigger-inbox/v1/inboxes/{inbox_id}/events — Subscribe to inbox notifications over SSE", "summary": "Subscribe to inbox notifications over SSE", "body": "# `getTriggerInboxEvents`\n\n> Subscribe to inbox notifications over SSE\n\n## High-level description\n\nOpens a Server-Sent Events stream that emits one frame per batch of newly-available messages on the inbox. The connection stays open until the JWT expires, at which point the server closes it.\n\nTwo kinds of frames are emitted:\n\n- **Data frames** (`data: {...}\\n\\n`) signal availability only, they do not include message content. Consumers should call the lease endpoint to retrieve messages. The JSON payload is described by the response schema below.\n- **Heartbeat frames** (`: keep-alive\\n\\n`) are SSE comment lines sent when no notification has arrived within the heartbeat interval. They are ignored by EventSource clients and exist only to keep intermediaries from closing the connection as idle.\n\n## Internals\n\n`GET https://api.zapier.com/trigger-inbox/v1/inboxes/{inbox_id}/events` from **Trigger Inbox API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n inbox_id: string; // in path — The unique identifier of the inbox to subscribe to.\n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"SSE stream opened. The response body is an open-ended sequence of `text/event-stream` frames.\",\n \"401\": \"Missing or invalid JWT in the Authorization header.\",\n \"404\": \"No inbox with the given id is visible to the authenticated user.\",\n \"503\": \"The notification backend was not reachable in time. Clients should retry.\"\n}\n```\n\n- Tags: Inboxes\n- Security: [{\"OAuth\": [\"external\"]}]\n\n## Example\n\n```http\nGET /trigger-inbox/v1/inboxes/{inbox_id}/events HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "GET /trigger-inbox/v1/inboxes/{inbox_id}/events", "signature": "GET /trigger-inbox/v1/inboxes/{inbox_id}/events", "aliases": [], "flags": [], "args": [{"name": "inbox_id", "in": "path", "required": true, "type": "string", "description": "The unique identifier of the inbox to subscribe to."}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "inboxes", "openapi"], "related": [], "meta": {"method": "GET", "path": "/trigger-inbox/v1/inboxes/{inbox_id}/events", "spec": "trigger-inbox.yaml", "api_title": "Trigger Inbox API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"200": "SSE stream opened. The response body is an open-ended sequence of `text/event-stream` frames.", "401": "Missing or invalid JWT in the Authorization header.", "404": "No inbox with the given id is visible to the authenticated user.", "503": "The notification backend was not reachable in time. Clients should retry."}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:listtriggerinboxmessages", "kind": "api_function", "key": "listTriggerInboxMessages", "title": "GET /trigger-inbox/v1/inboxes/{inbox_id}/messages — List messages from an inbox", "summary": "List messages from an inbox", "body": "# `listTriggerInboxMessages`\n\n> List messages from an inbox\n\n## High-level description\n\nList messages from an inbox for the authenticated user.\n\n## Internals\n\n`GET https://api.zapier.com/trigger-inbox/v1/inboxes/{inbox_id}/messages` from **Trigger Inbox API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n cursor?: string; // in query — The pagination cursor value.\n inbox_id: string; // in path — \n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"\",\n \"400\": \"Validation Error: Return fields with errors.\",\n \"429\": \"Too many requests.\"\n}\n```\n\n- Tags: Inbox Messages\n- Security: [{\"OAuth\": [\"external\"]}]\n\n## Example\n\n```http\nGET /trigger-inbox/v1/inboxes/{inbox_id}/messages HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "GET /trigger-inbox/v1/inboxes/{inbox_id}/messages", "signature": "GET /trigger-inbox/v1/inboxes/{inbox_id}/messages", "aliases": [], "flags": [], "args": [{"name": "cursor", "in": "query", "required": false, "type": "string", "description": "The pagination cursor value."}, {"name": "inbox_id", "in": "path", "required": true, "type": "string", "description": ""}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "inbox-messages", "openapi"], "related": [], "meta": {"method": "GET", "path": "/trigger-inbox/v1/inboxes/{inbox_id}/messages", "spec": "trigger-inbox.yaml", "api_title": "Trigger Inbox API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"200": "", "400": "Validation Error: Return fields with errors.", "429": "Too many requests."}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:leasetriggerinboxmessages", "kind": "api_function", "key": "leaseTriggerInboxMessages", "title": "POST /trigger-inbox/v1/inboxes/{inbox_id}/messages/lease — Lease messages from an inbox", "summary": "Lease messages from an inbox", "body": "# `leaseTriggerInboxMessages`\n\n> Lease messages from an inbox\n\n## High-level description\n\nLease messages from an inbox for the authenticated user.\n\n## Internals\n\n`POST https://api.zapier.com/trigger-inbox/v1/inboxes/{inbox_id}/messages/lease` from **Trigger Inbox API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n inbox_id: string; // in path — \n body?: LeaseRequest; // request JSON\n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"Response for a message lease request to an inbox.\",\n \"201\": \"Response for a message lease request to an inbox.\",\n \"409\": \"Response when leasing from a paused and fully drained inbox.\",\n \"400\": \"Validation Error: Return fields with errors.\",\n \"429\": \"Too many requests.\"\n}\n```\n\n- Tags: Inbox Messages\n- Security: [{\"OAuth\": [\"external\"]}]\n\n## Example\n\n```http\nPOST /trigger-inbox/v1/inboxes/{inbox_id}/messages/lease HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "POST /trigger-inbox/v1/inboxes/{inbox_id}/messages/lease", "signature": "POST /trigger-inbox/v1/inboxes/{inbox_id}/messages/lease", "aliases": [], "flags": [], "args": [{"name": "inbox_id", "in": "path", "required": true, "type": "string", "description": ""}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "inbox-messages", "openapi"], "related": [], "meta": {"method": "POST", "path": "/trigger-inbox/v1/inboxes/{inbox_id}/messages/lease", "spec": "trigger-inbox.yaml", "api_title": "Trigger Inbox API", "servers": ["https://api.zapier.com"], "request_schema": {"$ref": "#/components/schemas/LeaseRequest"}, "responses": {"200": "Response for a message lease request to an inbox.", "201": "Response for a message lease request to an inbox.", "409": "Response when leasing from a paused and fully drained inbox.", "400": "Validation Error: Return fields with errors.", "429": "Too many requests."}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:acknowledgetriggerinboxmessages", "kind": "api_function", "key": "acknowledgeTriggerInboxMessages", "title": "POST /trigger-inbox/v1/inboxes/{inbox_id}/messages/ack — Acknowledge messages from an inbox", "summary": "Acknowledge messages from an inbox", "body": "# `acknowledgeTriggerInboxMessages`\n\n> Acknowledge messages from an inbox\n\n## High-level description\n\nAcknowledge messages from an inbox for the authenticated user.\n\n## Internals\n\n`POST https://api.zapier.com/trigger-inbox/v1/inboxes/{inbox_id}/messages/ack` from **Trigger Inbox API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n inbox_id: string; // in path — \n body?: AckRequest; // request JSON\n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"Response for a message acknowledge request to an inbox.\",\n \"201\": \"Response for a message acknowledge request to an inbox.\",\n \"400\": \"Validation Error: Return fields with errors.\",\n \"429\": \"Too many requests.\"\n}\n```\n\n- Tags: Inbox Messages\n- Security: [{\"OAuth\": [\"external\"]}]\n\n## Example\n\n```http\nPOST /trigger-inbox/v1/inboxes/{inbox_id}/messages/ack HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "POST /trigger-inbox/v1/inboxes/{inbox_id}/messages/ack", "signature": "POST /trigger-inbox/v1/inboxes/{inbox_id}/messages/ack", "aliases": [], "flags": [], "args": [{"name": "inbox_id", "in": "path", "required": true, "type": "string", "description": ""}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "inbox-messages", "openapi"], "related": [], "meta": {"method": "POST", "path": "/trigger-inbox/v1/inboxes/{inbox_id}/messages/ack", "spec": "trigger-inbox.yaml", "api_title": "Trigger Inbox API", "servers": ["https://api.zapier.com"], "request_schema": {"$ref": "#/components/schemas/AckRequest"}, "responses": {"200": "Response for a message acknowledge request to an inbox.", "201": "Response for a message acknowledge request to an inbox.", "400": "Validation Error: Return fields with errors.", "429": "Too many requests."}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:releasetriggerinboxmessages", "kind": "api_function", "key": "releaseTriggerInboxMessages", "title": "POST /trigger-inbox/v1/inboxes/{inbox_id}/messages/release — Release leased messages without acknowledging", "summary": "Release leased messages without acknowledging", "body": "# `releaseTriggerInboxMessages`\n\n> Release leased messages without acknowledging\n\n## High-level description\n\nRelease the lease on one or more leased messages without acknowledging them. The messages become immediately available for leasing again. The original lease still counts against the per-message lease limit; releasing does not refund the attempt.\n\n## Internals\n\n`POST https://api.zapier.com/trigger-inbox/v1/inboxes/{inbox_id}/messages/release` from **Trigger Inbox API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n inbox_id: string; // in path — \n body?: ReleaseRequest; // request JSON\n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"Response for a message release request to an inbox.\",\n \"201\": \"Response for a message release request to an inbox.\",\n \"400\": \"Validation Error: Return fields with errors.\",\n \"429\": \"Too many requests.\"\n}\n```\n\n- Tags: Inbox Messages\n- Security: [{\"OAuth\": [\"external\"]}]\n\n## Example\n\n```http\nPOST /trigger-inbox/v1/inboxes/{inbox_id}/messages/release HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "POST /trigger-inbox/v1/inboxes/{inbox_id}/messages/release", "signature": "POST /trigger-inbox/v1/inboxes/{inbox_id}/messages/release", "aliases": [], "flags": [], "args": [{"name": "inbox_id", "in": "path", "required": true, "type": "string", "description": ""}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "inbox-messages", "openapi"], "related": [], "meta": {"method": "POST", "path": "/trigger-inbox/v1/inboxes/{inbox_id}/messages/release", "spec": "trigger-inbox.yaml", "api_title": "Trigger Inbox API", "servers": ["https://api.zapier.com"], "request_schema": {"$ref": "#/components/schemas/ReleaseRequest"}, "responses": {"200": "Response for a message release request to an inbox.", "201": "Response for a message release request to an inbox.", "400": "Validation Error: Return fields with errors.", "429": "Too many requests."}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "openapi:promotions-openapi.yaml", "kind": "openapi", "key": "promotions-openapi.yaml", "title": "Powered by Zapier Promotions API (promotions-openapi.yaml)", "summary": "The API to define promotions, powered by Zapier. See https://docs.zapier.com/powered-by-zapier/introduction for more information.", "body": "openapi: 3.1.0\ninfo:\n title: Powered by Zapier Promotions API\n version: promotions\n description: The API to define promotions, powered by Zapier. See https://docs.zapier.com/powered-by-zapier/introduction for more information.\n contact:\n name: Partner Sharing\npaths:\n /v2/promotions:\n post:\n operationId: root_create\n description: |-\n Enrolls an account into an existing promotion.\n\n Endpoint available to Partners only.\n The request must be authenticated by an [access token](https://docs.zapier.com/powered-by-zapier/api-reference/authentication#retrieving-a-user-access-token)\n that the user has granted to the Partner for the account.\n\n The `enrollment_id`, returned after successfully enrolling a user,\n **must** be stored by the partner in order to [retrieve](https://docs.zapier.com/powered-by-zapier/api-reference/promotions/get-enrollment)\n or [delete](https://docs.zapier.com/powered-by-zapier/api-reference/promotions/delete-enrollment) the enrollment.\n\n #### OAuth\n\n This endpoint requires the `promotions:write` OAuth scope.\n summary: Create a promotion enrollment\n tags:\n - Promotions\n - Experimental\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/PromotionEnrollment'\n examples:\n EnrollInAPromotion:\n value:\n promotion_id: promo_12345\n summary: Enroll in a promotion\n required: true\n security:\n - OAuth:\n - promotions:write\n responses:\n '201':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/PromotionEnrollmentResponse'\n description: Successful Enrollment\n '404':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/PromotionErrorResponse'\n examples:\n '404':\n value:\n errors:\n - status: '404'\n code: promotion_not_found\n title: Promotion Not Found\n detail: The requested promotion was not found. The specified promotion_id may be invalid.\n description: 404 Not Found\n '409':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/PromotionErrorResponse'\n examples:\n Conflict:\n value:\n errors:\n - status: '409'\n code: already_enrolled\n title: Already Enrolled\n detail: The provided account is already enrolled in the specified promotion.\n description: Conflict - User is already enrolled in this promotion\n '429':\n headers:\n Retry-After:\n schema:\n type: string\n format: uri\n description: Indicates when to retry the request\n X-RateLimit-Limit:\n schema:\n type: string\n format: uri\n description: The maximum number of requests you're permitted to make per hour.\n X-RateLimit-Remaining:\n schema:\n type: string\n format: uri\n description: The number of requests remaining in the current rate limit window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: uri\n description: The time at which the current rate limit window resets in UTC epoch seconds.\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/PromotionErrorResponse'\n description: ''\n '503':\n headers:\n Retry-After:\n schema:\n type: string\n format: uri\n description: Indicates when to retry the request\n X-RateLimit-Limit:\n schema:\n type: string\n format: uri\n description: The maximum number of requests you're permitted to make per hour.\n X-RateLimit-Remaining:\n schema:\n type: string\n format: uri\n description: The number of requests remaining in the current rate limit window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: uri\n description: The time at which the current rate limit window resets in UTC epoch seconds.\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/PromotionErrorResponse'\n description: ''\n '403':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/PromotionErrorResponse'\n examples:\n Forbidden:\n value:\n errors:\n - status: '403'\n code: permission_denied\n title: Permission Denied\n detail: You do not have permission to perform this action.\n description: Forbidden - User lacks permission to access this location\n '401':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/PromotionErrorResponse'\n examples:\n Access:\n value:\n errors:\n - status: '401'\n code: not_authenticated\n title: User Not Authenticated\n detail: User must be authenticated to access this resource. No valid user access token was provided.\n description: 'Access denied: User does not have permission for enrollment_id: enroll_67890'\n /v2/promotions/{enrollment_id}:\n get:\n operationId: root_retrieve\n description: |-\n Retrieve promotion enrollment details by enrollment ID.\n\n Endpoint available to Partners only.\n The request must be authenticated by a user access token\n that the user has granted to the Partner for the account.\n\n #### OAuth\n\n This endpoint requires the `promotions:read` OAuth scope.\n parameters:\n - in: path\n name: enrollment_id\n schema:\n type: string\n required: true\n tags:\n - Promotions\n - Experimental\n security:\n - OAuth:\n - promotions:read\n responses:\n '200':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/PromotionDetail'\n examples:\n GetPromotionDetails:\n value:\n promotion_id: test_promo\n enrollment_date: '2026-04-28T00:00:00Z'\n expiration_date: '2026-07-26T23:59:59Z'\n task_limit_per_month: 5\n tasks_used_this_month: 0\n status: enrolled\n summary: Get Promotion Details\n description: Succcessful retrieval of promotion details\n '404':\n description: No response body\n '429':\n headers:\n Retry-After:\n schema:\n type: string\n format: uri\n description: Indicates when to retry the request\n X-RateLimit-Limit:\n schema:\n type: string\n format: uri\n description: The maximum number of requests you're permitted to make per hour.\n X-RateLimit-Remaining:\n schema:\n type: string\n format: uri\n description: The number of requests remaining in the current rate limit window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: uri\n description: The time at which the current rate limit window resets in UTC epoch seconds.\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/PromotionErrorResponse'\n description: ''\n '503':\n headers:\n Retry-After:\n schema:\n type: string\n format: uri\n description: Indicates when to retry the request\n X-RateLimit-Limit:\n schema:\n type: string\n format: uri\n description: The maximum number of requests you're permitted to make per hour.\n X-RateLimit-Remaining:\n schema:\n type: string\n format: uri\n description: The number of requests remaining in the current rate limit window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: uri\n description: The time at which the current rate limit window resets in UTC epoch seconds.\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/PromotionErrorResponse'\n description: ''\n '403':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/PromotionErrorResponse'\n examples:\n Forbidden:\n value:\n errors:\n - status: '403'\n code: permission_denied\n title: Permission Denied\n detail: You do not have permission to perform this action.\n description: Forbidden - User lacks permission to access this location\n '401':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/PromotionErrorResponse'\n examples:\n Access:\n value:\n errors:\n - status: '401'\n code: not_authenticated\n title: User Not Authenticated\n detail: User must be authenticated to access this resource. No valid user access token was provided.\n description: 'Access denied: User does not have permission for enrollment_id: enroll_67890'\n delete:\n operationId: root_destroy\n description: |-\n Unenroll an account from a promotion.\n\n Endpoint available to Partners only.\n The request must be authenticated by an app access token the\n Partner has received using the Client Credentials flow.\n\n #### OAuth\n\n This endpoint requires the `promotions:write` OAuth scope.\n parameters:\n - in: path\n name: enrollment_id\n schema:\n type: string\n required: true\n tags:\n - Promotions\n - Experimental\n security:\n - OAuth:\n - promotions:write\n responses:\n '204':\n description: No response body\n '429':\n headers:\n Retry-After:\n schema:\n type: string\n format: uri\n description: Indicates when to retry the request\n X-RateLimit-Limit:\n schema:\n type: string\n format: uri\n description: The maximum number of requests you're permitted to make per hour.\n X-RateLimit-Remaining:\n schema:\n type: string\n format: uri\n description: The number of requests remaining in the current rate limit window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: uri\n description: The time at which the current rate limit window resets in UTC epoch seconds.\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/PromotionErrorResponse'\n description: ''\n '503':\n headers:\n Retry-After:\n schema:\n type: string\n format: uri\n description: Indicates when to retry the request\n X-RateLimit-Limit:\n schema:\n type: string\n format: uri\n description: The maximum number of requests you're permitted to make per hour.\n X-RateLimit-Remaining:\n schema:\n type: string\n format: uri\n description: The number of requests remaining in the current rate limit window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: uri\n description: The time at which the current rate limit window resets in UTC epoch seconds.\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/PromotionErrorResponse'\n description: ''\n '403':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/PromotionErrorResponse'\n examples:\n Forbidden:\n value:\n errors:\n - status: '403'\n code: permission_denied\n title: Permission Denied\n detail: You do not have permission to perform this action.\n description: Forbidden - User lacks permission to access this location\n '401':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/PromotionErrorResponse'\n examples:\n Access:\n value:\n errors:\n - status: '401'\n code: not_authenticated\n title: User Not Authenticated\n detail: User must be authenticated to access this resource. No valid user access token was provided.\n description: 'Access denied: User does not have permission for enrollment_id: enroll_67890'\ncomponents:\n schemas:\n PromotionDetail:\n type: object\n description: Succcessful retrieval of promotion details\n properties:\n promotion_id:\n type: string\n description: The unique identifier for the promotion\n enrollment_date:\n type:\n - string\n - 'null'\n format: date-time\n description: Date and time of enrollment\n expiration_date:\n type:\n - string\n - 'null'\n format: date-time\n description: Date and time when the promotion expires\n task_limit_per_month:\n type:\n - integer\n - 'null'\n description: Maximum number of tasks allowed per monthly billing cycle\n tasks_used_this_month:\n type: integer\n description: Number of tasks already used this monthly billing cycle (may not align with calendar month)\n status:\n type: string\n description: Current status of the enrollment\n required:\n - enrollment_date\n - expiration_date\n - promotion_id\n - status\n - task_limit_per_month\n - tasks_used_this_month\n PromotionEnrollment:\n type: object\n properties:\n promotion_id:\n type: string\n description: The unique identifier for the promotions\n required:\n - promotion_id\n PromotionEnrollmentResponse:\n type: object\n description: Successful Enrollment\n properties:\n enrollment_id:\n type: string\n description: The unique identifier for the enrollment. This must be stored by partners.\n required:\n - enrollment_id\n PromotionError:\n type: object\n properties:\n status:\n type: string\n description: HTTP status code of the error\n code:\n type: string\n description: Machine-readable error code\n title:\n type: string\n description: Human-readable error title\n detail:\n type: string\n description: Detailed description of the error\n required:\n - code\n - detail\n - status\n - title\n PromotionErrorResponse:\n type: object\n properties:\n errors:\n type: array\n items:\n $ref: '#/components/schemas/PromotionError'\n description: Errors encountered processing the request\n required:\n - errors\n securitySchemes:\n OAuth:\n type: oauth2\n description: The user access token for the user you would like to enroll. See our [OAuth2 authentication documentation](https://docs.zapier.com/powered-by-zapier/api-reference/authentication#retrieving-a-user-access-token).\n flows:\n authorizationCode:\n authorizationUrl: https://zapier.com/oauth/authorize/\n tokenUrl: https://zapier.com/oauth/token/\n refreshUrl: https://zapier.com/oauth/token/\n scopes:\n promotions:write: Enroll or unenroll accounts into promotions\n promotions:read: View usage of promotions you manage on an account\n clientCredentials:\n tokenUrl: /oauth/token\n scopes:\n promotions:write: Unenroll accounts from promotions\nservers:\n - url: https://api.zapier.com\n description: Production\ntags:\n - name: Promotions\n description: Operations related to managing Promotions\n - name: Experimental\n description: Operations that are not to be considered finalized, and are subject to change\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/api-reference/specs/promotions-openapi.yaml", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "openapi"], "related": [], "meta": {"title": "Powered by Zapier Promotions API", "version": "promotions", "servers": ["https://api.zapier.com"], "path_count": 2}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:root_create", "kind": "api_function", "key": "root_create", "title": "POST /v2/promotions — Create a promotion enrollment", "summary": "Create a promotion enrollment", "body": "# `root_create`\n\n> Create a promotion enrollment\n\n## High-level description\n\nEnrolls an account into an existing promotion.\n\nEndpoint available to Partners only.\nThe request must be authenticated by an [access token](https://docs.zapier.com/powered-by-zapier/api-reference/authentication#retrieving-a-user-access-token)\nthat the user has granted to the Partner for the account.\n\nThe `enrollment_id`, returned after successfully enrolling a user,\n**must** be stored by the partner in order to [retrieve](https://docs.zapier.com/powered-by-zapier/api-reference/promotions/get-enrollment)\nor [delete](https://docs.zapier.com/powered-by-zapier/api-reference/promotions/delete-enrollment) the enrollment.\n\n#### OAuth\n\nThis endpoint requires the `promotions:write` OAuth scope.\n\n## Internals\n\n`POST https://api.zapier.com/v2/promotions` from **Powered by Zapier Promotions API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n body?: PromotionEnrollment; // request JSON\n};\n```\n\n## Outputs\n\n```json\n{\n \"201\": \"Successful Enrollment\",\n \"404\": \"404 Not Found\",\n \"409\": \"Conflict - User is already enrolled in this promotion\",\n \"429\": \"\",\n \"503\": \"\",\n \"403\": \"Forbidden - User lacks permission to access this location\",\n \"401\": \"Access denied: User does not have permission for enrollment_id: enroll_67890\"\n}\n```\n\n- Tags: Promotions, Experimental\n- Security: [{\"OAuth\": [\"promotions:write\"]}]\n\n## Example\n\n```http\nPOST /v2/promotions HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "POST /v2/promotions", "signature": "POST /v2/promotions", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "openapi", "promotions"], "related": [], "meta": {"method": "POST", "path": "/v2/promotions", "spec": "promotions-openapi.yaml", "api_title": "Powered by Zapier Promotions API", "servers": ["https://api.zapier.com"], "request_schema": {"$ref": "#/components/schemas/PromotionEnrollment"}, "responses": {"201": "Successful Enrollment", "404": "404 Not Found", "409": "Conflict - User is already enrolled in this promotion", "429": "", "503": "", "403": "Forbidden - User lacks permission to access this location", "401": "Access denied: User does not have permission for enrollment_id: enroll_67890"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:root_retrieve", "kind": "api_function", "key": "root_retrieve", "title": "GET /v2/promotions/{enrollment_id} — root_retrieve", "summary": "Retrieve promotion enrollment details by enrollment ID.\n\nEndpoint available to Partners only.\nThe request must be authenticated by a user access token\nthat the user has granted to the Partner for the account.\n\n#### OAuth\n\nThis endpoint requires the `promotions:read` OAuth scope.", "body": "# `root_retrieve`\n\n> root_retrieve\n\n## High-level description\n\nRetrieve promotion enrollment details by enrollment ID.\n\nEndpoint available to Partners only.\nThe request must be authenticated by a user access token\nthat the user has granted to the Partner for the account.\n\n#### OAuth\n\nThis endpoint requires the `promotions:read` OAuth scope.\n\n## Internals\n\n`GET https://api.zapier.com/v2/promotions/{enrollment_id}` from **Powered by Zapier Promotions API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n enrollment_id: string; // in path — \n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"Succcessful retrieval of promotion details\",\n \"404\": \"No response body\",\n \"429\": \"\",\n \"503\": \"\",\n \"403\": \"Forbidden - User lacks permission to access this location\",\n \"401\": \"Access denied: User does not have permission for enrollment_id: enroll_67890\"\n}\n```\n\n- Tags: Promotions, Experimental\n- Security: [{\"OAuth\": [\"promotions:read\"]}]\n\n## Example\n\n```http\nGET /v2/promotions/{enrollment_id} HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "GET /v2/promotions/{enrollment_id}", "signature": "GET /v2/promotions/{enrollment_id}", "aliases": [], "flags": [], "args": [{"name": "enrollment_id", "in": "path", "required": true, "type": "string", "description": ""}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "openapi", "promotions"], "related": [], "meta": {"method": "GET", "path": "/v2/promotions/{enrollment_id}", "spec": "promotions-openapi.yaml", "api_title": "Powered by Zapier Promotions API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"200": "Succcessful retrieval of promotion details", "404": "No response body", "429": "", "503": "", "403": "Forbidden - User lacks permission to access this location", "401": "Access denied: User does not have permission for enrollment_id: enroll_67890"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:root_destroy", "kind": "api_function", "key": "root_destroy", "title": "DELETE /v2/promotions/{enrollment_id} — root_destroy", "summary": "Unenroll an account from a promotion.\n\nEndpoint available to Partners only.\nThe request must be authenticated by an app access token the\nPartner has received using the Client Credentials flow.\n\n#### OAuth\n\nThis endpoint requires the `promotions:write` OAuth scope.", "body": "# `root_destroy`\n\n> root_destroy\n\n## High-level description\n\nUnenroll an account from a promotion.\n\nEndpoint available to Partners only.\nThe request must be authenticated by an app access token the\nPartner has received using the Client Credentials flow.\n\n#### OAuth\n\nThis endpoint requires the `promotions:write` OAuth scope.\n\n## Internals\n\n`DELETE https://api.zapier.com/v2/promotions/{enrollment_id}` from **Powered by Zapier Promotions API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n enrollment_id: string; // in path — \n};\n```\n\n## Outputs\n\n```json\n{\n \"204\": \"No response body\",\n \"429\": \"\",\n \"503\": \"\",\n \"403\": \"Forbidden - User lacks permission to access this location\",\n \"401\": \"Access denied: User does not have permission for enrollment_id: enroll_67890\"\n}\n```\n\n- Tags: Promotions, Experimental\n- Security: [{\"OAuth\": [\"promotions:write\"]}]\n\n## Example\n\n```http\nDELETE /v2/promotions/{enrollment_id} HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "DELETE /v2/promotions/{enrollment_id}", "signature": "DELETE /v2/promotions/{enrollment_id}", "aliases": [], "flags": [], "args": [{"name": "enrollment_id", "in": "path", "required": true, "type": "string", "description": ""}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "openapi", "promotions"], "related": [], "meta": {"method": "DELETE", "path": "/v2/promotions/{enrollment_id}", "spec": "promotions-openapi.yaml", "api_title": "Powered by Zapier Promotions API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"204": "No response body", "429": "", "503": "", "403": "Forbidden - User lacks permission to access this location", "401": "Access denied: User does not have permission for enrollment_id: enroll_67890"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "openapi:workflow-api-schema.json", "kind": "openapi", "key": "workflow-api-schema.json", "title": "Partner API (workflow-api-schema.json)", "summary": "\n## Introduction\n\nThe Partner API is the best tool for complete style control over a user's Zapier experience within your app.\nEssentially, it lets you customize how you present Zapier within your product without sacrificing your app's look,\nfeel, and flow.\n\nThink of it as a native Zapier integration, helping you showcase your best Zapier-powered workflows where it's most\nhelpful to your users (wi", "body": "openapi: 3.1.0\ninfo:\n title: Partner API\n version: 2026.7.0\n description: |2\n\n ## Introduction\n\n The Partner API is the best tool for complete style control over a user's Zapier experience within your app.\n Essentially, it lets you customize how you present Zapier within your product without sacrificing your app's look,\n feel, and flow.\n\n Think of it as a native Zapier integration, helping you showcase your best Zapier-powered workflows where it's most\n helpful to your users (within the flow of your tool). You can customize styling, streamline Zap set-up for users,\n expose relevant Zap information, and more!\n\n With the Partner API, you can:\n\n - Get a list of all the apps available in Zapier's app directory so you can power your app directory and show your\n users all the integration possibilities with your Zapier integration.\n - Have complete style control over how you present Zap templates in your product. The Partner API gives you access\n to the raw Zap Template data so you can give your users access to your Zap template with your product's style, look\n and feel.\n - Get access to all your Zap templates and give your users the ability to search to quickly find the one they need.\n - Streamline Zap setup by pre-filling fields on behalf of your users.\n - Show users the Zaps they have set up from right within your product keeping them on your site longer and giving them\n complete confidence in their Zapier integration.\n - Embed our Zapier Editor to allow your users to create new Zaps and modify existing ones, without needing to leave\n your product.\n\n ## Authentication\n\n There are two ways to authenticate with the Partner API.\n\n 1. Your application's `client_id` which you will receive once you are approved for access to the API\n (Client ID Authentication)\n 2. A user's access token (Access Token Authentication).\n\n Which authentication method you should use depends on which endpoint(s) you are using.\n Review each endpoint's documentation to understand which parameters are required.\n\n > Note: while we do generate a `client_secret`, the type of grant we use (implicit) doesn't\n need it so it's not something we provide.'\n\n ## Learn more\n\n See the [Workflow API documentation](https://docs.zapier.com/partner-solutions/workflow-api/intro) for more information.\n contact:\n name: Zapier\n url: https://developer.zapier.com/contact\npaths:\n /v1/apps:\n get:\n operationId: v1_apps_list\n description: This endpoint returns a list of apps sorted popularity. See the\n List Apps guide to get started.\n summary: Get Apps v1\n parameters:\n - in: query\n name: category\n schema:\n type: string\n description: Categories that apps must have in order to be returned in the\n response\n example: google\n - in: query\n name: is_in_zap_template_with\n schema: {}\n description: If set, only return apps that are in a Zap Template with your\n app\n example: ''\n - in: query\n name: page\n schema:\n type: number\n description: Which page to return\n - in: query\n name: per_page\n schema:\n type: number\n description: Number of results to return per page\n - in: query\n name: title_search\n schema:\n type: string\n description: Case-insensitive parameter to limit the results to apps whose\n titles match\n example: google+calendar\n - in: query\n name: title_starts_with\n schema:\n type: string\n description: Case-insensitive parameter to only return apps whose titles start\n with the parameter value in the response\n example: google\n tags:\n - Apps\n security:\n - ClientIDAuthentication: []\n responses:\n '403':\n content:\n application/json:\n schema:\n type: object\n additionalProperties: {}\n description: 403 Response\n '401':\n description: Missing client_id in query parameters\n '409':\n content:\n application/json:\n schema:\n type: object\n additionalProperties: {}\n description: 409 Response\n '429':\n headers:\n Retry-After:\n schema:\n type: string\n format: uri\n description: Indicates when to retry the request\n X-RateLimit-Limit:\n schema:\n type: string\n format: uri\n description: The maximum number of requests you're permitted to make\n per hour.\n X-RateLimit-Remaining:\n schema:\n type: string\n format: uri\n description: The number of requests remaining in the current rate limit\n window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: uri\n description: The time at which the current rate limit window resets\n in UTC epoch seconds.\n content:\n application/json:\n schema:\n type: object\n additionalProperties: {}\n description: 429 Response\n '503':\n headers:\n Retry-After:\n schema:\n type: string\n format: uri\n description: Indicates when to retry the request\n X-RateLimit-Limit:\n schema:\n type: string\n format: uri\n description: The maximum number of requests you're permitted to make\n per hour.\n X-RateLimit-Remaining:\n schema:\n type: string\n format: uri\n description: The number of requests remaining in the current rate limit\n window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: uri\n description: The time at which the current rate limit window resets\n in UTC epoch seconds.\n content:\n application/json:\n schema:\n type: object\n additionalProperties: {}\n description: 503 Response\n '504':\n content:\n application/json:\n schema:\n type: object\n additionalProperties: {}\n description: 504 Response\n '200':\n content:\n application/json:\n schema:\n type: array\n items:\n $ref: '#/components/schemas/AppsResponse'\n examples:\n /v1/apps:\n value:\n - total: 3649\n page: 2\n pages: 1825\n per_page: 2\n objects:\n - uuid: ca83afc5-ee9a-470d-b577-e7f8fd555b67\n title: Slack\n slug: slack\n description: 'Slack is a platform for team communication: everything\n in one place, instantly searchable, available wherever you\n go. Offering instant messaging, document sharing and knowledge\n search for modern teams.'\n image: https://zapier-images.imgix.net/storage/services/6cf3f5a461feadfba7abc93c4c395b33_2.png?auto=format%2Ccompress&ixlib=python-3.0.0&q=50\n url: https://api.zapier.com/v1/embed/apps/google-ads/integrations/slack\n links:\n mutual:zap_templates: https://api.zapier.com/v1/zap-templates?apps=slack&utm_source=partner&utm_medium=embed&utm_campaign=partner_api&referer=zapier\n categories:\n - slug: team-chat\n images:\n url_16x16: https://zapier-images.imgix.net/storage/services/6cf3f5a461feadfba7abc93c4c395b33_2.png?auto=format%2Ccompress&fit=crop&h=16&ixlib=python-3.0.0&q=50&w=16\n url_32x32: https://zapier-images.imgix.net/storage/services/6cf3f5a461feadfba7abc93c4c395b33_2.png?auto=format%2Ccompress&fit=crop&h=32&ixlib=python-3.0.0&q=50&w=32\n url_64x64: https://zapier-images.imgix.net/storage/services/6cf3f5a461feadfba7abc93c4c395b33_2.png?auto=format%2Ccompress&fit=crop&h=64&ixlib=python-3.0.0&q=50&w=64\n url_128x128: https://zapier-images.imgix.net/storage/services/6cf3f5a461feadfba7abc93c4c395b33_2.png?auto=format%2Ccompress&fit=crop&h=128&ixlib=python-3.0.0&q=50&w=128\n app_latest: SlackCLIAPI@latest\n - uuid: d74234df-0045-436e-bd5b-ee577e74e6b8\n title: Google Calendar\n slug: google-calendar\n description: Google Calendar lets you organize your schedule\n and share events with co-workers and friends. With Google's\n free online calendar, it's easy to keep track of your daily\n schedule.\n image: https://zapier-images.imgix.net/storage/services/62c82a7958c6c29736f17d0495b6635c.png?auto=format%2Ccompress&ixlib=python-3.0.0&q=50\n url: https://api.zapier.com/v1/embed/apps/google-ads/integrations/google-calendar\n links:\n mutual:zap_templates: https://api.zapier.com/v1/zap-templates?apps=google-calendar&utm_source=partner&utm_medium=embed&utm_campaign=partner_api&referer=zapier\n categories:\n - slug: calendar\n - slug: google\n images:\n url_16x16: https://zapier-images.imgix.net/storage/services/62c82a7958c6c29736f17d0495b6635c.png?auto=format%2Ccompress&fit=crop&h=16&ixlib=python-3.0.0&q=50&w=16\n url_32x32: https://zapier-images.imgix.net/storage/services/62c82a7958c6c29736f17d0495b6635c.png?auto=format%2Ccompress&fit=crop&h=32&ixlib=python-3.0.0&q=50&w=32\n url_64x64: https://zapier-images.imgix.net/storage/services/62c82a7958c6c29736f17d0495b6635c.png?auto=format%2Ccompress&fit=crop&h=64&ixlib=python-3.0.0&q=50&w=64\n url_128x128: https://zapier-images.imgix.net/storage/services/62c82a7958c6c29736f17d0495b6635c.png?auto=format%2Ccompress&fit=crop&h=128&ixlib=python-3.0.0&q=50&w=128\n app_latest: GoogleCalendarCLIAPI@latest\n prev_url: https://api.zapier.com/v1/apps?per_page=2&page=1\n next_url: https://api.zapier.com/v1/apps?per_page=2&page=3\n description: |2\n\n - Your own app will not be returned.\n - Zapier built-in apps will not be returned.\n - Order of the result is by app popularity.\n description: ''\n /v1/categories:\n get:\n operationId: v1_categories_list\n description: List of Zap categories\n summary: Get Categories\n parameters:\n - in: query\n name: limit\n schema:\n type: number\n default: 10\n description: Limit the number of Zap categories returned.\n - in: query\n name: offset\n schema:\n type: number\n default: 0\n description: The number of Zap categories to skip over. The default value\n is 0, which is the offset of the first item.\n tags:\n - Categories\n responses:\n '403':\n content:\n application/json:\n schema:\n type: object\n additionalProperties: {}\n description: 403 Response\n '401':\n content:\n application/json:\n schema:\n type: object\n additionalProperties: {}\n description: 401 Response\n '409':\n content:\n application/json:\n schema:\n type: object\n additionalProperties: {}\n description: 409 Response\n '429':\n headers:\n Retry-After:\n schema:\n type: string\n format: uri\n description: Indicates when to retry the request\n X-RateLimit-Limit:\n schema:\n type: string\n format: uri\n description: The maximum number of requests you're permitted to make\n per hour.\n X-RateLimit-Remaining:\n schema:\n type: string\n format: uri\n description: The number of requests remaining in the current rate limit\n window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: uri\n description: The time at which the current rate limit window resets\n in UTC epoch seconds.\n content:\n application/json:\n schema:\n type: object\n additionalProperties: {}\n description: 429 Response\n '503':\n headers:\n Retry-After:\n schema:\n type: string\n format: uri\n description: Indicates when to retry the request\n X-RateLimit-Limit:\n schema:\n type: string\n format: uri\n description: The maximum number of requests you're permitted to make\n per hour.\n X-RateLimit-Remaining:\n schema:\n type: string\n format: uri\n description: The number of requests remaining in the current rate limit\n window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: uri\n description: The time at which the current rate limit window resets\n in UTC epoch seconds.\n content:\n application/json:\n schema:\n type: object\n additionalProperties: {}\n description: 503 Response\n '504':\n content:\n application/json:\n schema:\n type: object\n additionalProperties: {}\n description: 504 Response\n '200':\n content:\n application/json:\n schema:\n type: array\n items:\n $ref: '#/components/schemas/CategoriesResponse'\n examples:\n /v1/categories:\n value:\n - next: https://api.zapier.com/v1/categories?offset=10&limit=10\n previous: null\n count: 90\n objects:\n - id: 78\n title: Ads & Conversion\n slug: ads-conversion\n description: Tools to track and reach an audience online.\n url: https://zapier.com/api/v4/app-directory/categories/ads-conversion/\n type_of: curated\n featured_entry_slug: boost-google-ads-ROI-with-zapier\n role: child\n - id: 1\n title: Accounting\n slug: accounting\n description: Tools for accounting and finance.\n url: https://zapier.com/api/v4/app-directory/categories/accounting/\n type_of: curated\n featured_entry_slug: favorite-zaps-accounting\n role: child\n - id: 14\n title: AI Tools\n slug: ai-tools\n description: Unlock the potential of artificial intelligence\n in your workflow with these AI integrations. These apps use\n AI to tackle everything from natural language processing to\n image classification, providing you with unparalleled automation\n power.\n url: https://zapier.com/api/v4/app-directory/categories/ai-tools/\n type_of: curated\n featured_entry_slug: null\n role: parent\n - id: 97\n title: All\n slug: all\n description: Contains all the services.\n url: https://zapier.com/api/v4/app-directory/categories/all/\n type_of: auto\n featured_entry_slug: null\n role: parent\n - id: 37\n title: Amazon\n slug: aws\n description: Tools from Amazon to host and manage sites and\n applications on the Amazon cloud.\n url: https://zapier.com/api/v4/app-directory/categories/aws/\n type_of: curated\n featured_entry_slug: what-you-should-automate\n role: child\n - id: 84\n title: Analytics\n slug: analytics\n description: Tools to measure and report on success\n url: https://zapier.com/api/v4/app-directory/categories/analytics/\n type_of: curated\n featured_entry_slug: automate-analytics-tools\n role: child\n - id: 21\n title: App Builder\n slug: app-builder\n description: Tools to build a custom app with forms and databases.\n url: https://zapier.com/api/v4/app-directory/categories/app-builder/\n type_of: curated\n featured_entry_slug: null\n role: child\n - id: 35\n title: App Families\n slug: app-families\n description: ''\n url: https://zapier.com/api/v4/app-directory/categories/app-families/\n type_of: curated\n featured_entry_slug: null\n role: parent\n - id: 155\n title: Artificial Intelligence\n slug: artificial-intelligence\n description: Unlock the potential of artificial intelligence\n in your workflow with these AI integrations. These apps use\n AI to tackle everything from natural language processing to\n image classification, providing you with unparalleled automation\n power.\n url: https://zapier.com/api/v4/app-directory/categories/artificial-intelligence/\n type_of: curated\n featured_entry_slug: null\n role: parent\n - id: 46\n title: Beta\n slug: beta\n description: Beta services.\n url: https://zapier.com/api/v4/app-directory/categories/beta/\n type_of: auto\n featured_entry_slug: null\n role: child\n description: ''\n /v1/profiles/me:\n get:\n operationId: v1_profiles_me_list\n description: |-\n This endpoint returns the authenticated user information\n\n #### When using OAuth\n\n This endpoint requires the `profile` OAuth scope.\n summary: User Profile\n tags:\n - Accounts\n security:\n - OAuth:\n - profile\n responses:\n '403':\n description: Invalid authentication\n '401':\n content:\n application/json:\n schema:\n type: object\n additionalProperties: {}\n description: 401 Response\n '409':\n content:\n application/json:\n schema:\n type: object\n additionalProperties: {}\n description: 409 Response\n '429':\n headers:\n Retry-After:\n schema:\n type: string\n format: uri\n description: Indicates when to retry the request\n X-RateLimit-Limit:\n schema:\n type: string\n format: uri\n description: The maximum number of requests you're permitted to make\n per hour.\n X-RateLimit-Remaining:\n schema:\n type: string\n format: uri\n description: The number of requests remaining in the current rate limit\n window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: uri\n description: The time at which the current rate limit window resets\n in UTC epoch seconds.\n content:\n application/json:\n schema:\n type: object\n additionalProperties: {}\n description: 429 Response\n '503':\n headers:\n Retry-After:\n schema:\n type: string\n format: uri\n description: Indicates when to retry the request\n X-RateLimit-Limit:\n schema:\n type: string\n format: uri\n description: The maximum number of requests you're permitted to make\n per hour.\n X-RateLimit-Remaining:\n schema:\n type: string\n format: uri\n description: The number of requests remaining in the current rate limit\n window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: uri\n description: The time at which the current rate limit window resets\n in UTC epoch seconds.\n content:\n application/json:\n schema:\n type: object\n additionalProperties: {}\n description: 503 Response\n '504':\n content:\n application/json:\n schema:\n type: object\n additionalProperties: {}\n description: 504 Response\n '200':\n content:\n application/json:\n schema:\n type: array\n items:\n $ref: '#/components/schemas/Profile'\n examples:\n Profile:\n value:\n - id: 88998899\n first_name: Jacob\n last_name: Corwin\n full_name: Jacob Corwin\n email: jacob.corwin@zapier.example\n email_confirmed: true\n timezone: America/Toronto\n summary: profile\n description: ''\n /v1/zap-templates:\n get:\n operationId: v1_zap_templates_list\n description: List popular Zap Templates using your app. See our List Zap Templates\n guide to get started.\n summary: Get Zap Templates\n parameters:\n - in: query\n name: apps\n schema:\n type: string\n description: |-\n A comma separated list of Zapier Apps to match Zap templates against. Note:\n - Your app will always be one of the apps in the template\n - The list will return Zap Templates with all the provided apps, not a subset\n example: mailchimp\n - in: query\n name: limit\n schema:\n type: number\n default: 5\n description: '(Max: 100) Limit the number of Zap templates returned.'\n - in: query\n name: offset\n schema:\n type: number\n default: 0\n description: The number of Zap templates to skip before beginning to return\n the Zap templates. The default value is 0, which is the offset of the first\n item.\n tags:\n - Zap Templates\n security:\n - ClientIDAuthentication: []\n responses:\n '403':\n content:\n application/json:\n schema:\n type: object\n additionalProperties: {}\n description: 403 Response\n '401':\n description: Missing client_id in query parameters\n '409':\n content:\n application/json:\n schema:\n type: object\n additionalProperties: {}\n description: 409 Response\n '429':\n headers:\n Retry-After:\n schema:\n type: string\n format: uri\n description: Indicates when to retry the request\n X-RateLimit-Limit:\n schema:\n type: string\n format: uri\n description: The maximum number of requests you're permitted to make\n per hour.\n X-RateLimit-Remaining:\n schema:\n type: string\n format: uri\n description: The number of requests remaining in the current rate limit\n window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: uri\n description: The time at which the current rate limit window resets\n in UTC epoch seconds.\n content:\n application/json:\n schema:\n type: object\n additionalProperties: {}\n description: 429 Response\n '503':\n headers:\n Retry-After:\n schema:\n type: string\n format: uri\n description: Indicates when to retry the request\n X-RateLimit-Limit:\n schema:\n type: string\n format: uri\n description: The maximum number of requests you're permitted to make\n per hour.\n X-RateLimit-Remaining:\n schema:\n type: string\n format: uri\n description: The number of requests remaining in the current rate limit\n window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: uri\n description: The time at which the current rate limit window resets\n in UTC epoch seconds.\n content:\n application/json:\n schema:\n type: object\n additionalProperties: {}\n description: 503 Response\n '504':\n content:\n application/json:\n schema:\n type: object\n additionalProperties: {}\n description: 504 Response\n '200':\n content:\n application/json:\n schema:\n type: array\n items:\n $ref: '#/components/schemas/ZapTemplate'\n examples:\n /v1/zap-templates:\n value:\n - id: 51652\n steps:\n - id: 1\n uuid: b9df4eff-f311-44f9-ac54-2901f952c6ac\n title: Google Ads\n slug: google-ads\n description: Google Ads (formerly Google AdWords) is an online\n advertising platform developed by Google, where advertisers\n pay to display brief advertisements, service offerings, product\n listings, video content, and generate mobile application installs\n within the Google ad network to web users.\n image: https://zapier-images.imgix.net/storage/services/4058ec8b47ad751cbd39bd686cf4eab7.png?auto=format%2Ccompress&ixlib=python-3.0.0&q=50\n hex_color: 4285F4\n images:\n url_16x16: https://zapier-images.imgix.net/storage/services/4058ec8b47ad751cbd39bd686cf4eab7.png?auto=format%2Ccompress&fit=crop&h=16&ixlib=python-3.0.0&q=50&w=16\n url_32x32: https://zapier-images.imgix.net/storage/services/4058ec8b47ad751cbd39bd686cf4eab7.png?auto=format%2Ccompress&fit=crop&h=32&ixlib=python-3.0.0&q=50&w=32\n url_64x64: https://zapier-images.imgix.net/storage/services/4058ec8b47ad751cbd39bd686cf4eab7.png?auto=format%2Ccompress&fit=crop&h=64&ixlib=python-3.0.0&q=50&w=64\n url_128x128: https://zapier-images.imgix.net/storage/services/4058ec8b47ad751cbd39bd686cf4eab7.png?auto=format%2Ccompress&fit=crop&h=128&ixlib=python-3.0.0&q=50&w=128\n api: GoogleAdsCLIAPI@3.0.0\n url: https://zapier.com/apps/google-ads/integrations?utm_medium=partner_api\n label: New Campaign\n - id: 2\n uuid: ca83afc5-ee9a-470d-b577-e7f8fd555b67\n title: Slack\n slug: slack\n description: 'Slack is a platform for team communication: everything\n in one place, instantly searchable, available wherever you\n go. Offering instant messaging, document sharing and knowledge\n search for modern teams.'\n image: https://zapier-images.imgix.net/storage/services/6cf3f5a461feadfba7abc93c4c395b33_2.png?auto=format%2Ccompress&ixlib=python-3.0.0&q=50\n hex_color: 510f4d\n images:\n url_16x16: https://zapier-images.imgix.net/storage/services/6cf3f5a461feadfba7abc93c4c395b33_2.png?auto=format%2Ccompress&fit=crop&h=16&ixlib=python-3.0.0&q=50&w=16\n url_32x32: https://zapier-images.imgix.net/storage/services/6cf3f5a461feadfba7abc93c4c395b33_2.png?auto=format%2Ccompress&fit=crop&h=32&ixlib=python-3.0.0&q=50&w=32\n url_64x64: https://zapier-images.imgix.net/storage/services/6cf3f5a461feadfba7abc93c4c395b33_2.png?auto=format%2Ccompress&fit=crop&h=64&ixlib=python-3.0.0&q=50&w=64\n url_128x128: https://zapier-images.imgix.net/storage/services/6cf3f5a461feadfba7abc93c4c395b33_2.png?auto=format%2Ccompress&fit=crop&h=128&ixlib=python-3.0.0&q=50&w=128\n api: SlackAPI\n url: https://zapier.com/apps/slack/integrations?utm_medium=partner_api\n label: Send Channel Message\n title: Send messages to Slack channels whenever new Google Ads\n campaigns launch\n slug: send-messages-to-slack-channels-whenever-new-google-ads-campaigns-launch\n status: published\n description_plain: |\n A new Google Ads campaign can mean the start of your next marketing push, but it can also mean the start of a ton of new sales and service workflows. Zapier gives you a head start on those projects by automatically posting a new message in Slack to a specific channel you choose. Give your teams the heads up they need before your new clients come rolling in!\n description_raw: A new Google Ads campaign can mean the start\n of your next marketing push, but it can also mean the start\n of a ton of new sales and service workflows. Zapier gives you\n a head start on those projects by automatically posting a new\n message in Slack to a specific channel you choose. Give your\n teams the heads up they need before your new clients come rolling\n in!\n url: https://zapier.com/apps/google-ads/integrations/slack/51652/send-messages-to-slack-channels-whenever-new-google-ads-campaigns-launch?utm_medium=partner_api\n description: |\n <p>A new Google Ads campaign can mean the start of your next marketing push, but it can also mean the start of a ton of new sales and service workflows. Zapier gives you a head start on those projects by automatically posting a new message in Slack to a specific channel you choose. Give your teams the heads up they need before your new clients come rolling in!</p>\n create_url: https://api.zapier.com/v1/embed/google-ads/create/51652\n type: guided_zap\n description: ''\n /v1/zaps:\n get:\n operationId: v1_zaps_list\n description: |-\n This endpoint returns a list of Zaps for the authenticated Zapier user.\n\n #### When using OAuth\n\n This endpoint requires the `zap` OAuth scope.\n summary: Get Zaps v1\n parameters:\n - in: query\n name: get_params\n schema: {}\n description: If set, guarantees that the 'params' of any node belonging to\n your app will be present in the response\n example: ''\n - in: query\n name: limit\n schema:\n type: number\n default: 5\n description: '(Max: 100) Limit the number of Zap templates returned.'\n - in: query\n name: offset\n schema:\n type: number\n default: 0\n description: The number of Zap templates to skip before beginning to return\n the Zap templates. The default value is 0, which is the offset of the first\n item.\n - in: query\n name: params__{{KEY}}\n schema:\n type: string\n description: Filter for Zaps that contain the given parameter's {{KEY}} and\n the value of the query parameter. Keys are defined by your app on the [developer\n platform](https://zapier.com/platform/login).\n example: ex@mp1e47c4e6ff1a44e7800\n tags:\n - Zaps\n security:\n - OAuth:\n - zap\n responses:\n '403':\n description: Invalid authentication\n '401':\n content:\n application/json:\n schema:\n type: object\n additionalProperties: {}\n description: 401 Response\n '409':\n content:\n application/json:\n schema:\n type: object\n additionalProperties: {}\n description: 409 Response\n '429':\n headers:\n Retry-After:\n schema:\n type: string\n format: uri\n description: Indicates when to retry the request\n X-RateLimit-Limit:\n schema:\n type: string\n format: uri\n description: The maximum number of requests you're permitted to make\n per hour.\n X-RateLimit-Remaining:\n schema:\n type: string\n format: uri\n description: The number of requests remaining in the current rate limit\n window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: uri\n description: The time at which the current rate limit window resets\n in UTC epoch seconds.\n content:\n application/json:\n schema:\n type: object\n additionalProperties: {}\n description: 429 Response\n '503':\n headers:\n Retry-After:\n schema:\n type: string\n format: uri\n description: Indicates when to retry the request\n X-RateLimit-Limit:\n schema:\n type: string\n format: uri\n description: The maximum number of requests you're permitted to make\n per hour.\n X-RateLimit-Remaining:\n schema:\n type: string\n format: uri\n description: The number of requests remaining in the current rate limit\n window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: uri\n description: The time at which the current rate limit window resets\n in UTC epoch seconds.\n content:\n application/json:\n schema:\n type: object\n additionalProperties: {}\n description: 503 Response\n '504':\n content:\n application/json:\n schema:\n type: object\n additionalProperties: {}\n description: 504 Response\n '200':\n content:\n application/json:\n schema:\n type: array\n items:\n $ref: '#/components/schemas/ZapsResponse'\n examples:\n /v1/zaps:\n value:\n - next: https://api.zapier.com/v1/zaps?limit=2&offset=2\n previous: null\n count: 2\n objects:\n - id: 125\n title: Create Trello cards from new Typeform entries\n state: 'on'\n steps:\n - type_of: read\n app:\n id: 4259\n uuid: 5e2ba0e469b0-4754-bf69-d46221122aa2\n title: Typeform\n slug: typeform\n description: Typeform helps you ask awesomely online! If\n you ever need to run a survey, questionnaire, form, contest\n etc... Typeform will help you achieve it beautifully across\n all devices, every time, using its next generation platform.\n hex_color: 8bcbca\n image: https://cdn.zapier.com/storage/developer/5e21b4c1e0a2a3346a801dbc0a2a5a6d_2.png\n images:\n url_16x16: https://cdn.zapier.com/storage/developer/5e21b4c1e0a2a3346a801dbc0a2a5a6d_2.16x16.png\n url_32x32: https://cdn.zapier.com/storage/developer/5e21b4c1e0a2a3346a801dbc0a2a5a6d_2.32x32.png\n url_64x64: https://cdn.zapier.com/storage/developer/5e21b4c1e0a2a3346a801dbc0a2a5a6d_2.64x64.png\n url_128x128: https://cdn.zapier.com/storage/developer/5e21b4c1e0a2a3346a801dbc0a2a5a6d_2.128x128.png\n api: TypeformDevAPI\n url: https://zapier.com/apps/typeform/integrations?utm_source=partner&utm_medium=embed&utm_campaign=partner_api&referer=zapier\n params: null\n - type_of: write\n app:\n id: 4192\n uuid: ee7e5c50a7d2-4bb4-b5b8-a7e55aa00521\n title: Trello\n slug: trello\n description: Trello is team collaboration tool that lets\n you organize anything and everything to keep your projects\n on task.\n hex_color: 0079bf\n image: https://cdn.zapier.com/storage/services/da3ff465abd3a3e1b687c52ff803af74.png\n images:\n url_16x16: https://cdn.zapier.com/storage/services/da3ff465abd3a3e1b687c52ff803af74.16x16.png\n url_32x32: https://cdn.zapier.com/storage/services/da3ff465abd3a3e1b687c52ff803af74.32x32.png\n url_64x64: https://cdn.zapier.com/storage/services/da3ff465abd3a3e1b687c52ff803af74.64x64.png\n url_128x128: https://cdn.zapier.com/storage/services/da3ff465abd3a3e1b687c52ff803af74.128x128.png\n api: TrelloAPI\n url: https://zapier.com/apps/trello/integrations?utm_source=partner&utm_medium=embed&utm_campaign=partner_api&referer=zapier\n params: null\n url: https://zapier.com/editor/125?utm_source=partner&utm_medium=embed&utm_campaign=partner_api&referer=zapier\n modified_at: '2017-03-22T09:38:11-05:00'\n - id: 123\n title: Create Trello cards from new Typeform entries\n state: 'off'\n steps:\n - type_of: read\n app:\n id: 4259\n uuid: 5e2ba0e469b0-4754-bf69-d46221122aa2\n title: Typeform\n slug: typeform\n description: Typeform helps you ask awesomely online! If\n you ever need to run a survey, questionnaire, form, contest\n etc... Typeform will help you achieve it beautifully across\n all devices, every time, using its next generation platform.\n hex_color: 8bcbca\n image: https://cdn.zapier.com/storage/developer/5e21b4c1e0a2a3346a801dbc0a2a5a6d_2.png\n images:\n url_16x16: https://cdn.zapier.com/storage/developer/5e21b4c1e0a2a3346a801dbc0a2a5a6d_2.16x16.png\n url_32x32: https://cdn.zapier.com/storage/developer/5e21b4c1e0a2a3346a801dbc0a2a5a6d_2.32x32.png\n url_64x64: https://cdn.zapier.com/storage/developer/5e21b4c1e0a2a3346a801dbc0a2a5a6d_2.64x64.png\n url_128x128: https://cdn.zapier.com/storage/developer/5e21b4c1e0a2a3346a801dbc0a2a5a6d_2.128x128.png\n api: TypeformDevAPI\n url: https://zapier.com/apps/typeform/integrations?utm_source=partner&utm_medium=embed&utm_campaign=partner_api&referer=zapier\n params: null\n - type_of: write\n app:\n id: 4192\n uuid: ee7e5c50a7d2-4bb4-b5b8-a7e55aa00521\n title: Trello\n slug: trello\n description: Trello is team collaboration tool that lets\n you organize anything and everything to keep your projects\n on task.\n hex_color: 0079bf\n image: https://cdn.zapier.com/storage/services/da3ff465abd3a3e1b687c52ff803af74.png\n images:\n url_16x16: https://cdn.zapier.com/storage/services/da3ff465abd3a3e1b687c52ff803af74.16x16.png\n url_32x32: https://cdn.zapier.com/storage/services/da3ff465abd3a3e1b687c52ff803af74.32x32.png\n url_64x64: https://cdn.zapier.com/storage/services/da3ff465abd3a3e1b687c52ff803af74.64x64.png\n url_128x128: https://cdn.zapier.com/storage/services/da3ff465abd3a3e1b687c52ff803af74.128x128.png\n api: TrelloAPI\n url: https://zapier.com/apps/trello/integrations?utm_source=partner&utm_medium=embed&utm_campaign=partner_api&referer=zapier\n params: null\n url: https://zapier.com/editor/123?utm_source=partner&utm_medium=embed&utm_campaign=partner_api&referer=zapier\n modified_at: '2017-03-21T22:04:05-05:00'\n description: ''\n /v2/action-runs:\n post:\n operationId: create-action-run\n description: |-\n Runs an action (step) in the third party API, using the provided authentication and inputs.\n\n This endpoint is asynchronous, and the response will contain an Action Run ID. You can use the `/v2/action-runs/:id` endpoint to check the status of the run and retrieve the results.\n\n Optionally, include a `callback_url` in the request body to receive the result via a POST callback instead of polling.\n\n #### When using OAuth\n\n This endpoint requires the `action:run` OAuth scope.\n summary: Create an Action Run\n tags:\n - Experimental\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/RunActionRequest'\n examples:\n CreatingAnActionRun(runningAnAction):\n value:\n data:\n action: example_core:Vn7xbE60\n authentication: example_QVaAreV1\n inputs:\n email: me@example.com\n callback_url: https://example.com/post_callback\n summary: Creating an Action Run (running an action)\n required: true\n security:\n - OAuth:\n - action:run\n responses:\n '200':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/RunActionResponse'\n examples:\n CreateActionRunResponse:\n value:\n data:\n type: run\n id: 123e4567-e89b-12d3-a456-426614174000\n summary: Create Action Run Response\n description: ''\n '403':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 403 Response\n '401':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 401 Response\n '409':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 409 Response\n '429':\n headers:\n Retry-After:\n schema:\n type: string\n format: uri\n description: Indicates when to retry the request\n X-RateLimit-Limit:\n schema:\n type: string\n format: uri\n description: The maximum number of requests you're permitted to make\n per hour.\n X-RateLimit-Remaining:\n schema:\n type: string\n format: uri\n description: The number of requests remaining in the current rate limit\n window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: uri\n description: The time at which the current rate limit window resets\n in UTC epoch seconds.\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 429 Response\n '503':\n headers:\n Retry-After:\n schema:\n type: string\n format: uri\n description: Indicates when to retry the request\n X-RateLimit-Limit:\n schema:\n type: string\n format: uri\n description: The maximum number of requests you're permitted to make\n per hour.\n X-RateLimit-Remaining:\n schema:\n type: string\n format: uri\n description: The number of requests remaining in the current rate limit\n window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: uri\n description: The time at which the current rate limit window resets\n in UTC epoch seconds.\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 503 Response\n '504':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 504 Response\n '400':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n examples:\n MalformedRequest.:\n value:\n errors:\n - status: 400\n code: parse_error\n title: ParseError\n detail: Malformed request.\n source: null\n meta:\n source: ZAPIER\n full_details:\n message: Malformed request.\n code: parse_error\n summary: Malformed request.\n description: This schema can be expected for 4xx 'Malformed request.' errors\n '500':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n examples:\n AServerErrorOccurred.:\n value:\n errors:\n - status: 500\n code: error\n title: APIException\n detail: A server error occurred.\n source: null\n meta:\n source: ZAPIER\n full_details:\n message: A server error occurred.\n code: error\n summary: A server error occurred.\n description: This schema can be expected for 5xx 'A server error occurred.'\n errors\n callbacks:\n actionRunCompleted:\n '{$request.body#/data/callback_url}':\n post:\n description: When the action run reaches a terminal state (success or\n error), Zapier POSTs the result to the `callback_url` supplied in\n the request. The callback includes a `Zapier-Callback-Signature` header\n containing an RS256-signed JWT verifiable via Zapier's JWKS endpoint\n at `https://zapier.com/.well-known/jwks.json`. Zapier retries on 5xx\n responses and network errors (up to 3 attempts). 4xx responses are\n not retried.\n summary: Action run completion callback\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/CallbackPayload'\n required: true\n responses:\n 2XX:\n description: Callback acknowledged\n /v2/action-runs/{id}:\n get:\n operationId: retrieve-action-run\n description: |-\n Retrieves an Action Run.\n\n #### When using OAuth\n\n This endpoint requires the `action:run` OAuth scope.\n summary: Retrieve Action Run\n parameters:\n - in: path\n name: id\n schema:\n type: string\n description: An Action Run ID.\n required: true\n tags:\n - Experimental\n security:\n - OAuth:\n - action:run\n responses:\n '200':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ActionRunResponse'\n examples:\n RetrievingARun:\n value:\n data:\n type: run\n status: success\n results:\n - id: 123\n errors: []\n summary: Retrieving a run\n description: ''\n '403':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 403 Response\n '401':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 401 Response\n '409':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 409 Response\n '429':\n headers:\n Retry-After:\n schema:\n type: string\n format: uri\n description: Indicates when to retry the request\n X-RateLimit-Limit:\n schema:\n type: string\n format: uri\n description: The maximum number of requests you're permitted to make\n per hour.\n X-RateLimit-Remaining:\n schema:\n type: string\n format: uri\n description: The number of requests remaining in the current rate limit\n window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: uri\n description: The time at which the current rate limit window resets\n in UTC epoch seconds.\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 429 Response\n '503':\n headers:\n Retry-After:\n schema:\n type: string\n format: uri\n description: Indicates when to retry the request\n X-RateLimit-Limit:\n schema:\n type: string\n format: uri\n description: The maximum number of requests you're permitted to make\n per hour.\n X-RateLimit-Remaining:\n schema:\n type: string\n format: uri\n description: The number of requests remaining in the current rate limit\n window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: uri\n description: The time at which the current rate limit window resets\n in UTC epoch seconds.\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 503 Response\n '504':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 504 Response\n '400':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n examples:\n MalformedRequest.:\n value:\n errors:\n - status: 400\n code: parse_error\n title: ParseError\n detail: Malformed request.\n source: null\n meta:\n source: ZAPIER\n full_details:\n message: Malformed request.\n code: parse_error\n summary: Malformed request.\n description: This schema can be expected for 4xx 'Malformed request.' errors\n '500':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n examples:\n AServerErrorOccurred.:\n value:\n errors:\n - status: 500\n code: error\n title: APIException\n detail: A server error occurred.\n source: null\n meta:\n source: ZAPIER\n full_details:\n message: A server error occurred.\n code: error\n summary: A server error occurred.\n description: This schema can be expected for 5xx 'A server error occurred.'\n errors\n /v2/actions:\n get:\n operationId: get-actions\n description: |-\n Fetch the available actions for the provided App. It's typical to filter by type so that only actions that make sense for a particular step are shown. Action IDs may not be reused, see our documentation for how to hardcode a particular action.\n\n #### When using Client ID\n\n Simply providing a client ID query parameter is sufficient. If an Authorization header is present, it will be used instead.\n\n #### When using OAuth\n\n This endpoint requires the `zap` OAuth scope.\n summary: Get Actions\n parameters:\n - in: query\n name: action_type\n schema:\n type: string\n enum:\n - READ\n - READ_BULK\n - SEARCH\n - SEARCH_AND_WRITE\n - SEARCH_OR_WRITE\n - WRITE\n description: The type of Action to filter for. Defaults to returning all actions\n regardless of type.\n example: READ\n - in: query\n name: app\n schema:\n type: string\n description: 'An App identifier: a canonical App ID (UUID) or an app key'\n required: true\n example: 868f9d3c-2ea0-4f19-a32d-a61b276ab8de\n tags:\n - Actions\n - Apps\n security:\n - OAuth:\n - zap\n - ClientIDAuthentication: []\n responses:\n '200':\n content:\n application/json:\n schema:\n type: array\n items:\n $ref: '#/components/schemas/ActionsResponse'\n examples:\n ActionsExample:\n value:\n - links:\n next: null\n prev: null\n meta:\n count: 1\n limit: 10\n offset: 0\n data:\n - id: uag:1f188536-6dd0-4172-8414-2b90914ddee9\n key: new_lead\n app: 83b47c0e-adda-44da-a45d-42565fe521ef\n type: action\n action_type: action\n is_instant: true\n title: New Lead\n description: Triggers when a new lead is added to SuperExampleCRM\n description: ''\n '403':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 403 Response\n '401':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 401 Response\n '409':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 409 Response\n '429':\n headers:\n Retry-After:\n schema:\n type: string\n format: uri\n description: Indicates when to retry the request\n X-RateLimit-Limit:\n schema:\n type: string\n format: uri\n description: The maximum number of requests you're permitted to make\n per hour.\n X-RateLimit-Remaining:\n schema:\n type: string\n format: uri\n description: The number of requests remaining in the current rate limit\n window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: uri\n description: The time at which the current rate limit window resets\n in UTC epoch seconds.\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 429 Response\n '503':\n headers:\n Retry-After:\n schema:\n type: string\n format: uri\n description: Indicates when to retry the request\n X-RateLimit-Limit:\n schema:\n type: string\n format: uri\n description: The maximum number of requests you're permitted to make\n per hour.\n X-RateLimit-Remaining:\n schema:\n type: string\n format: uri\n description: The number of requests remaining in the current rate limit\n window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: uri\n description: The time at which the current rate limit window resets\n in UTC epoch seconds.\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 503 Response\n '504':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 504 Response\n '400':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n examples:\n MalformedRequest.:\n value:\n errors:\n - status: 400\n code: parse_error\n title: ParseError\n detail: Malformed request.\n source: null\n meta:\n source: ZAPIER\n full_details:\n message: Malformed request.\n code: parse_error\n summary: Malformed request.\n description: This schema can be expected for 4xx 'Malformed request.' errors\n '500':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n examples:\n AServerErrorOccurred.:\n value:\n errors:\n - status: 500\n code: error\n title: APIException\n detail: A server error occurred.\n source: null\n meta:\n source: ZAPIER\n full_details:\n message: A server error occurred.\n code: error\n summary: A server error occurred.\n description: This schema can be expected for 5xx 'A server error occurred.'\n errors\n /v2/actions/{action_id}/inputs:\n post:\n operationId: get-fields-inputs\n description: |-\n Get the Input Fields for a particular Action, using the provided authentication and inputs. See the fields and fieldsets guide for more information.\n\n By default the Input Fields are resolved against the App's current version. Pass a versioned `selected_api` (e.g. `SplitwiseCLIAPI@1.0.0`) to pin them to a specific version instead, which is useful when editing an Action that was created against an earlier version of the App.\n See [our docs](https://docs.zapier.com/powered-by-zapier/zap-creation/fields-and-fieldsets#input-fields) for more information.\n\n #### When using OAuth\n\n This endpoint requires the `zap:write` OAuth scope.\n summary: Get Input Fields\n parameters:\n - in: path\n name: action_id\n schema:\n type: string\n description: An Action ID, as provided by the `/actions` endpoint.\n required: true\n example: uag:87b1c14e-ef30-43d5-9395-6c6514dbb123\n tags:\n - Actions\n - Inputs\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ListInputFieldsRequest'\n examples:\n FetchInputFields:\n value:\n data:\n authentication: '928117'\n inputs:\n spreadsheet: my_sheet\n summary: Fetch input fields\n FetchInputFieldsForASpecificAppVersion:\n value:\n data:\n authentication: '928117'\n inputs:\n spreadsheet: my_sheet\n selected_api: GoogleSheetsCLIAPI@1.0.0\n summary: Fetch input fields for a specific App version\n required: true\n security:\n - OAuth:\n - zap:write\n responses:\n '200':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/InputFieldsResponse'\n examples:\n InputFieldsForSomeApp:\n value:\n links:\n next: null\n prev: null\n meta:\n count: 2\n limit: null\n offset: 0\n data:\n - type: input_field\n id: input\n default_value: ''\n depends_on: []\n description: Use the Input Data fields above to assign key names\n (left) and map values (right) from previous steps. Use notation\n `inputData.keyName` or `inputData['keyName']` to access the\n values within your code. The data will be provided **as strings**.\n Learn more [here](https://zapier.com/help/create/code-webhooks/use-javascript-code-in-zaps#input-data-for-code-steps).\n invalidates_input_fields: false\n is_required: false\n placeholder: ''\n title: Input Data\n value_type: OBJECT\n - type: input_field\n id: code\n default_value: |-\n // this is wrapped in an `async` function\n // you can use await throughout the function\n\n output = [{id: 123, hello: \"world\"}];\n depends_on: []\n description: '**Warning! This is an advanced action!** Uses\n Node 10.x.x. Please read the [Code documentation for more\n information](/help/create/code-webhooks/use-javascript-code-in-zaps).'\n format: CODE\n invalidates_input_fields: false\n is_required: true\n placeholder: ''\n title: Code\n value_type: STRING\n summary: Input fields for some app\n description: ''\n '403':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 403 Response\n '401':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 401 Response\n '409':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 409 Response\n '429':\n headers:\n Retry-After:\n schema:\n type: string\n format: uri\n description: Indicates when to retry the request\n X-RateLimit-Limit:\n schema:\n type: string\n format: uri\n description: The maximum number of requests you're permitted to make\n per hour.\n X-RateLimit-Remaining:\n schema:\n type: string\n format: uri\n description: The number of requests remaining in the current rate limit\n window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: uri\n description: The time at which the current rate limit window resets\n in UTC epoch seconds.\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 429 Response\n '503':\n headers:\n Retry-After:\n schema:\n type: string\n format: uri\n description: Indicates when to retry the request\n X-RateLimit-Limit:\n schema:\n type: string\n format: uri\n description: The maximum number of requests you're permitted to make\n per hour.\n X-RateLimit-Remaining:\n schema:\n type: string\n format: uri\n description: The number of requests remaining in the current rate limit\n window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: uri\n description: The time at which the current rate limit window resets\n in UTC epoch seconds.\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 503 Response\n '504':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 504 Response\n '400':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n examples:\n MalformedRequest.:\n value:\n errors:\n - status: 400\n code: parse_error\n title: ParseError\n detail: Malformed request.\n source: null\n meta:\n source: ZAPIER\n full_details:\n message: Malformed request.\n code: parse_error\n summary: Malformed request.\n description: This schema can be expected for 4xx 'Malformed request.' errors\n '500':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n examples:\n AServerErrorOccurred.:\n value:\n errors:\n - status: 500\n code: error\n title: APIException\n detail: A server error occurred.\n source: null\n meta:\n source: ZAPIER\n full_details:\n message: A server error occurred.\n code: error\n summary: A server error occurred.\n description: This schema can be expected for 5xx 'A server error occurred.'\n errors\n /v2/actions/{action_id}/inputs/{input_id}/choices:\n post:\n operationId: get-choices\n description: |-\n Get the possible values for a `SELECT` Input Field.\n\n #### When using OAuth\n\n This endpoint requires the `zap` OAuth scope.\n summary: Get Choices\n parameters:\n - in: path\n name: action_id\n schema:\n type: string\n description: An Action ID, as provided by the `/actions` endpoint.\n required: true\n example: uag:87b1c14e-ef30-43d5-9395-6c6514dbb123\n - in: path\n name: input_id\n schema:\n type: string\n description: An Input Field ID, as provided by the `/inputs` endpoint.\n required: true\n example: lead_id\n - in: query\n name: page\n schema:\n type: string\n default: '1'\n description: The page of choices to return, defaults to the first\n example: '1'\n tags:\n - Actions\n - Inputs\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ChoiceRequest'\n required: true\n security:\n - OAuth:\n - zap\n responses:\n '200':\n content:\n application/json:\n schema:\n type: array\n items:\n $ref: '#/components/schemas/ChoiceResponse'\n examples:\n ChoicesForSomeAction:\n value:\n - data:\n - id: 55c\n type: choice\n label: First\n value: example\n - id: a73\n type: choice\n label: Second\n value: example\n links:\n next: null\n prev: null\n meta:\n page: 1\n summary: Choices for Some Action\n description: ''\n '403':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 403 Response\n '401':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 401 Response\n '409':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 409 Response\n '429':\n headers:\n Retry-After:\n schema:\n type: string\n format: uri\n description: Indicates when to retry the request\n X-RateLimit-Limit:\n schema:\n type: string\n format: uri\n description: The maximum number of requests you're permitted to make\n per hour.\n X-RateLimit-Remaining:\n schema:\n type: string\n format: uri\n description: The number of requests remaining in the current rate limit\n window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: uri\n description: The time at which the current rate limit window resets\n in UTC epoch seconds.\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 429 Response\n '503':\n headers:\n Retry-After:\n schema:\n type: string\n format: uri\n description: Indicates when to retry the request\n X-RateLimit-Limit:\n schema:\n type: string\n format: uri\n description: The maximum number of requests you're permitted to make\n per hour.\n X-RateLimit-Remaining:\n schema:\n type: string\n format: uri\n description: The number of requests remaining in the current rate limit\n window.\n X-RateLimit-Reset:\n schema:\n type: string\n format: uri\n description: The time at which the current rate limit window resets\n in UTC epoch seconds.\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 503 Response\n '504':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n description: 504 Response\n '400':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n examples:\n MalformedRequest.:\n value:\n errors:\n - status: 400\n code: parse_error\n title: ParseError\n detail: Malformed request.\n source: null\n meta:\n source: ZAPIER\n full_details:\n message: Malformed request.\n code: parse_error\n summary: Malformed request.\n description: This schema can be expected for 4xx 'Malformed request.' errors\n '500':\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ErrorResponse'\n examples:\n AServerErrorOccurred.:\n value:\n errors:\n - status: 500\n code: error\n title: APIException\n detail: A server error occurred.\n source: null\n meta:\n source: ZAPIER\n full_details:\n message: A server error occurred.\n code: error\n summary: A server error occurred.\n description: This schema can be expected for 5xx 'A server error occurred.'\n errors\n /v2/actions/{action_id}/outputs:\n post:\n operationId: get-fields-outputs\n description: |-\n Get the Output Fields for a particular Action, using the provided authentication and inputs.\n\n #### When using OAuth\n\n This endpoint requires the `zap:write` OAuth scope.\n summary: Get Output Fields\n parameters:\n - in: path\n name: action_id\n schema:\n type: string\n description: An Action ID, as provided by the `/actions` endpoint.\n required: true\n example: uag:87b1c14e-ef30-43d5-9395-6c6514dbb123\n tags:\n - Actions\n - Outputs\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/ListOutputFieldsRequest'\n examples:\n FetchingOutputsForSomeApp:\n value:\n data:\n authentication: example_QVaAreV1\n inputs:\n someparam: somevalue\n summary: Fetching outputs for some app\n required: true\n security:\n - OAuth:\n - zap:write\n responses:\n '200':\n content:\n application/json:\n schema:\n $ref: '#/compo\n\n…[truncated]", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://api.zapier.com/schema", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "openapi"], "related": [], "meta": {"title": "Partner API", "version": "2026.7.0", "servers": ["https://api.zapier.com"], "path_count": 23}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:v1_apps_list", "kind": "api_function", "key": "v1_apps_list", "title": "GET /v1/apps — Get Apps v1", "summary": "Get Apps v1", "body": "# `v1_apps_list`\n\n> Get Apps v1\n\n## High-level description\n\nThis endpoint returns a list of apps sorted popularity. See the List Apps guide to get started.\n\n## Internals\n\n`GET https://api.zapier.com/v1/apps` from **Partner API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n category?: string; // in query — Categories that apps must have in order to be returned in the response\n is_in_zap_template_with?: unknown; // in query — If set, only return apps that are in a Zap Template with your app\n page?: number; // in query — Which page to return\n per_page?: number; // in query — Number of results to return per page\n title_search?: string; // in query — Case-insensitive parameter to limit the results to apps whose titles match\n title_starts_with?: string; // in query — Case-insensitive parameter to only return apps whose titles start with the parameter value in the re\n};\n```\n\n## Outputs\n\n```json\n{\n \"403\": \"403 Response\",\n \"401\": \"Missing client_id in query parameters\",\n \"409\": \"409 Response\",\n \"429\": \"429 Response\",\n \"503\": \"503 Response\",\n \"504\": \"504 Response\",\n \"200\": \"\"\n}\n```\n\n- Tags: Apps\n- Security: [{\"ClientIDAuthentication\": []}]\n\n## Example\n\n```http\nGET /v1/apps HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "GET /v1/apps", "signature": "GET /v1/apps", "aliases": [], "flags": [], "args": [{"name": "category", "in": "query", "required": false, "type": "string", "description": "Categories that apps must have in order to be returned in the response"}, {"name": "is_in_zap_template_with", "in": "query", "required": false, "type": "unknown", "description": "If set, only return apps that are in a Zap Template with your app"}, {"name": "page", "in": "query", "required": false, "type": "number", "description": "Which page to return"}, {"name": "per_page", "in": "query", "required": false, "type": "number", "description": "Number of results to return per page"}, {"name": "title_search", "in": "query", "required": false, "type": "string", "description": "Case-insensitive parameter to limit the results to apps whose titles match"}, {"name": "title_starts_with", "in": "query", "required": false, "type": "string", "description": "Case-insensitive parameter to only return apps whose titles start with the parameter value in the response"}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "apps", "openapi"], "related": [], "meta": {"method": "GET", "path": "/v1/apps", "spec": "workflow-api-schema.json", "api_title": "Partner API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"403": "403 Response", "401": "Missing client_id in query parameters", "409": "409 Response", "429": "429 Response", "503": "503 Response", "504": "504 Response", "200": ""}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:v1_categories_list", "kind": "api_function", "key": "v1_categories_list", "title": "GET /v1/categories — Get Categories", "summary": "Get Categories", "body": "# `v1_categories_list`\n\n> Get Categories\n\n## High-level description\n\nList of Zap categories\n\n## Internals\n\n`GET https://api.zapier.com/v1/categories` from **Partner API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n limit?: number; // in query — Limit the number of Zap categories returned.\n offset?: number; // in query — The number of Zap categories to skip over. The default value is 0, which is the offset of the first \n};\n```\n\n## Outputs\n\n```json\n{\n \"403\": \"403 Response\",\n \"401\": \"401 Response\",\n \"409\": \"409 Response\",\n \"429\": \"429 Response\",\n \"503\": \"503 Response\",\n \"504\": \"504 Response\",\n \"200\": \"\"\n}\n```\n\n- Tags: Categories\n- Security: []\n\n## Example\n\n```http\nGET /v1/categories HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "GET /v1/categories", "signature": "GET /v1/categories", "aliases": [], "flags": [], "args": [{"name": "limit", "in": "query", "required": false, "type": "number", "description": "Limit the number of Zap categories returned."}, {"name": "offset", "in": "query", "required": false, "type": "number", "description": "The number of Zap categories to skip over. The default value is 0, which is the offset of the first item."}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "categories", "openapi"], "related": [], "meta": {"method": "GET", "path": "/v1/categories", "spec": "workflow-api-schema.json", "api_title": "Partner API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"403": "403 Response", "401": "401 Response", "409": "409 Response", "429": "429 Response", "503": "503 Response", "504": "504 Response", "200": ""}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:v1_profiles_me_list", "kind": "api_function", "key": "v1_profiles_me_list", "title": "GET /v1/profiles/me — User Profile", "summary": "User Profile", "body": "# `v1_profiles_me_list`\n\n> User Profile\n\n## High-level description\n\nThis endpoint returns the authenticated user information\n\n#### When using OAuth\n\nThis endpoint requires the `profile` OAuth scope.\n\n## Internals\n\n`GET https://api.zapier.com/v1/profiles/me` from **Partner API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n // no parameters\n};\n```\n\n## Outputs\n\n```json\n{\n \"403\": \"Invalid authentication\",\n \"401\": \"401 Response\",\n \"409\": \"409 Response\",\n \"429\": \"429 Response\",\n \"503\": \"503 Response\",\n \"504\": \"504 Response\",\n \"200\": \"\"\n}\n```\n\n- Tags: Accounts\n- Security: [{\"OAuth\": [\"profile\"]}]\n\n## Example\n\n```http\nGET /v1/profiles/me HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "GET /v1/profiles/me", "signature": "GET /v1/profiles/me", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["accounts", "api", "openapi"], "related": [], "meta": {"method": "GET", "path": "/v1/profiles/me", "spec": "workflow-api-schema.json", "api_title": "Partner API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"403": "Invalid authentication", "401": "401 Response", "409": "409 Response", "429": "429 Response", "503": "503 Response", "504": "504 Response", "200": ""}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:v1_zap_templates_list", "kind": "api_function", "key": "v1_zap_templates_list", "title": "GET /v1/zap-templates — Get Zap Templates", "summary": "Get Zap Templates", "body": "# `v1_zap_templates_list`\n\n> Get Zap Templates\n\n## High-level description\n\nList popular Zap Templates using your app. See our List Zap Templates guide to get started.\n\n## Internals\n\n`GET https://api.zapier.com/v1/zap-templates` from **Partner API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n apps?: string; // in query — A comma separated list of Zapier Apps to match Zap templates against. Note:\n- Your app will always b\n limit?: number; // in query — (Max: 100) Limit the number of Zap templates returned.\n offset?: number; // in query — The number of Zap templates to skip before beginning to return the Zap templates. The default value \n};\n```\n\n## Outputs\n\n```json\n{\n \"403\": \"403 Response\",\n \"401\": \"Missing client_id in query parameters\",\n \"409\": \"409 Response\",\n \"429\": \"429 Response\",\n \"503\": \"503 Response\",\n \"504\": \"504 Response\",\n \"200\": \"\"\n}\n```\n\n- Tags: Zap Templates\n- Security: [{\"ClientIDAuthentication\": []}]\n\n## Example\n\n```http\nGET /v1/zap-templates HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "GET /v1/zap-templates", "signature": "GET /v1/zap-templates", "aliases": [], "flags": [], "args": [{"name": "apps", "in": "query", "required": false, "type": "string", "description": "A comma separated list of Zapier Apps to match Zap templates against. Note:\n- Your app will always be one of the apps in the template\n- The list will return Zap Templates with all the provided apps, not a subset"}, {"name": "limit", "in": "query", "required": false, "type": "number", "description": "(Max: 100) Limit the number of Zap templates returned."}, {"name": "offset", "in": "query", "required": false, "type": "number", "description": "The number of Zap templates to skip before beginning to return the Zap templates. The default value is 0, which is the offset of the first item."}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "openapi", "zap-templates"], "related": [], "meta": {"method": "GET", "path": "/v1/zap-templates", "spec": "workflow-api-schema.json", "api_title": "Partner API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"403": "403 Response", "401": "Missing client_id in query parameters", "409": "409 Response", "429": "429 Response", "503": "503 Response", "504": "504 Response", "200": ""}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:v1_zaps_list", "kind": "api_function", "key": "v1_zaps_list", "title": "GET /v1/zaps — Get Zaps v1", "summary": "Get Zaps v1", "body": "# `v1_zaps_list`\n\n> Get Zaps v1\n\n## High-level description\n\nThis endpoint returns a list of Zaps for the authenticated Zapier user.\n\n#### When using OAuth\n\nThis endpoint requires the `zap` OAuth scope.\n\n## Internals\n\n`GET https://api.zapier.com/v1/zaps` from **Partner API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n get_params?: unknown; // in query — If set, guarantees that the 'params' of any node belonging to your app will be present in the respon\n limit?: number; // in query — (Max: 100) Limit the number of Zap templates returned.\n offset?: number; // in query — The number of Zap templates to skip before beginning to return the Zap templates. The default value \n params__{{KEY}}?: string; // in query — Filter for Zaps that contain the given parameter's {{KEY}} and the value of the query parameter. Key\n};\n```\n\n## Outputs\n\n```json\n{\n \"403\": \"Invalid authentication\",\n \"401\": \"401 Response\",\n \"409\": \"409 Response\",\n \"429\": \"429 Response\",\n \"503\": \"503 Response\",\n \"504\": \"504 Response\",\n \"200\": \"\"\n}\n```\n\n- Tags: Zaps\n- Security: [{\"OAuth\": [\"zap\"]}]\n\n## Example\n\n```http\nGET /v1/zaps HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "GET /v1/zaps", "signature": "GET /v1/zaps", "aliases": [], "flags": [], "args": [{"name": "get_params", "in": "query", "required": false, "type": "unknown", "description": "If set, guarantees that the 'params' of any node belonging to your app will be present in the response"}, {"name": "limit", "in": "query", "required": false, "type": "number", "description": "(Max: 100) Limit the number of Zap templates returned."}, {"name": "offset", "in": "query", "required": false, "type": "number", "description": "The number of Zap templates to skip before beginning to return the Zap templates. The default value is 0, which is the offset of the first item."}, {"name": "params__{{KEY}}", "in": "query", "required": false, "type": "string", "description": "Filter for Zaps that contain the given parameter's {{KEY}} and the value of the query parameter. Keys are defined by your app on the [developer platform](https://zapier.com/platform/login)."}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "openapi", "zaps"], "related": [], "meta": {"method": "GET", "path": "/v1/zaps", "spec": "workflow-api-schema.json", "api_title": "Partner API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"403": "Invalid authentication", "401": "401 Response", "409": "409 Response", "429": "429 Response", "503": "503 Response", "504": "504 Response", "200": ""}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:create-action-run", "kind": "api_function", "key": "create-action-run", "title": "POST /v2/action-runs — Create an Action Run", "summary": "Create an Action Run", "body": "# `create-action-run`\n\n> Create an Action Run\n\n## High-level description\n\nRuns an action (step) in the third party API, using the provided authentication and inputs.\n\nThis endpoint is asynchronous, and the response will contain an Action Run ID. You can use the `/v2/action-runs/:id` endpoint to check the status of the run and retrieve the results.\n\nOptionally, include a `callback_url` in the request body to receive the result via a POST callback instead of polling.\n\n#### When using OAuth\n\nThis endpoint requires the `action:run` OAuth scope.\n\n## Internals\n\n`POST https://api.zapier.com/v2/action-runs` from **Partner API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n body?: RunActionRequest; // request JSON\n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"\",\n \"403\": \"403 Response\",\n \"401\": \"401 Response\",\n \"409\": \"409 Response\",\n \"429\": \"429 Response\",\n \"503\": \"503 Response\",\n \"504\": \"504 Response\",\n \"400\": \"This schema can be expected for 4xx 'Malformed request.' errors\",\n \"500\": \"This schema can be expected for 5xx 'A server error occurred.' errors\"\n}\n```\n\n- Tags: Experimental\n- Security: [{\"OAuth\": [\"action:run\"]}]\n\n## Example\n\n```http\nPOST /v2/action-runs HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "POST /v2/action-runs", "signature": "POST /v2/action-runs", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "experimental", "openapi"], "related": [], "meta": {"method": "POST", "path": "/v2/action-runs", "spec": "workflow-api-schema.json", "api_title": "Partner API", "servers": ["https://api.zapier.com"], "request_schema": {"$ref": "#/components/schemas/RunActionRequest"}, "responses": {"200": "", "403": "403 Response", "401": "401 Response", "409": "409 Response", "429": "429 Response", "503": "503 Response", "504": "504 Response", "400": "This schema can be expected for 4xx 'Malformed request.' errors", "500": "This schema can be expected for 5xx 'A server error occurred.' errors"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:retrieve-action-run", "kind": "api_function", "key": "retrieve-action-run", "title": "GET /v2/action-runs/{id} — Retrieve Action Run", "summary": "Retrieve Action Run", "body": "# `retrieve-action-run`\n\n> Retrieve Action Run\n\n## High-level description\n\nRetrieves an Action Run.\n\n#### When using OAuth\n\nThis endpoint requires the `action:run` OAuth scope.\n\n## Internals\n\n`GET https://api.zapier.com/v2/action-runs/{id}` from **Partner API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n id: string; // in path — An Action Run ID.\n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"\",\n \"403\": \"403 Response\",\n \"401\": \"401 Response\",\n \"409\": \"409 Response\",\n \"429\": \"429 Response\",\n \"503\": \"503 Response\",\n \"504\": \"504 Response\",\n \"400\": \"This schema can be expected for 4xx 'Malformed request.' errors\",\n \"500\": \"This schema can be expected for 5xx 'A server error occurred.' errors\"\n}\n```\n\n- Tags: Experimental\n- Security: [{\"OAuth\": [\"action:run\"]}]\n\n## Example\n\n```http\nGET /v2/action-runs/{id} HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "GET /v2/action-runs/{id}", "signature": "GET /v2/action-runs/{id}", "aliases": [], "flags": [], "args": [{"name": "id", "in": "path", "required": true, "type": "string", "description": "An Action Run ID."}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "experimental", "openapi"], "related": [], "meta": {"method": "GET", "path": "/v2/action-runs/{id}", "spec": "workflow-api-schema.json", "api_title": "Partner API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"200": "", "403": "403 Response", "401": "401 Response", "409": "409 Response", "429": "429 Response", "503": "503 Response", "504": "504 Response", "400": "This schema can be expected for 4xx 'Malformed request.' errors", "500": "This schema can be expected for 5xx 'A server error occurred.' errors"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:get-actions", "kind": "api_function", "key": "get-actions", "title": "GET /v2/actions — Get Actions", "summary": "Get Actions", "body": "# `get-actions`\n\n> Get Actions\n\n## High-level description\n\nFetch the available actions for the provided App. It's typical to filter by type so that only actions that make sense for a particular step are shown. Action IDs may not be reused, see our documentation for how to hardcode a particular action.\n\n#### When using Client ID\n\nSimply providing a client ID query parameter is sufficient. If an Authorization header is present, it will be used instead.\n\n#### When using OAuth\n\nThis endpoint requires the `zap` OAuth scope.\n\n## Internals\n\n`GET https://api.zapier.com/v2/actions` from **Partner API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n action_type?: string; // in query — The type of Action to filter for. Defaults to returning all actions regardless of type.\n app: string; // in query — An App identifier: a canonical App ID (UUID) or an app key\n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"\",\n \"403\": \"403 Response\",\n \"401\": \"401 Response\",\n \"409\": \"409 Response\",\n \"429\": \"429 Response\",\n \"503\": \"503 Response\",\n \"504\": \"504 Response\",\n \"400\": \"This schema can be expected for 4xx 'Malformed request.' errors\",\n \"500\": \"This schema can be expected for 5xx 'A server error occurred.' errors\"\n}\n```\n\n- Tags: Actions, Apps\n- Security: [{\"OAuth\": [\"zap\"]}, {\"ClientIDAuthentication\": []}]\n\n## Example\n\n```http\nGET /v2/actions HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "GET /v2/actions", "signature": "GET /v2/actions", "aliases": [], "flags": [], "args": [{"name": "action_type", "in": "query", "required": false, "type": "string", "description": "The type of Action to filter for. Defaults to returning all actions regardless of type."}, {"name": "app", "in": "query", "required": true, "type": "string", "description": "An App identifier: a canonical App ID (UUID) or an app key"}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["actions", "api", "openapi"], "related": [], "meta": {"method": "GET", "path": "/v2/actions", "spec": "workflow-api-schema.json", "api_title": "Partner API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"200": "", "403": "403 Response", "401": "401 Response", "409": "409 Response", "429": "429 Response", "503": "503 Response", "504": "504 Response", "400": "This schema can be expected for 4xx 'Malformed request.' errors", "500": "This schema can be expected for 5xx 'A server error occurred.' errors"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:get-fields-inputs", "kind": "api_function", "key": "get-fields-inputs", "title": "POST /v2/actions/{action_id}/inputs — Get Input Fields", "summary": "Get Input Fields", "body": "# `get-fields-inputs`\n\n> Get Input Fields\n\n## High-level description\n\nGet the Input Fields for a particular Action, using the provided authentication and inputs. See the fields and fieldsets guide for more information.\n\nBy default the Input Fields are resolved against the App's current version. Pass a versioned `selected_api` (e.g. `SplitwiseCLIAPI@1.0.0`) to pin them to a specific version instead, which is useful when editing an Action that was created against an earlier version of the App.\nSee [our docs](https://docs.zapier.com/powered-by-zapier/zap-creation/fields-and-fieldsets#input-fields) for more information.\n\n#### When using OAuth\n\nThis endpoint requires the `zap:write` OAuth scope.\n\n## Internals\n\n`POST https://api.zapier.com/v2/actions/{action_id}/inputs` from **Partner API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n action_id: string; // in path — An Action ID, as provided by the `/actions` endpoint.\n body?: ListInputFieldsRequest; // request JSON\n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"\",\n \"403\": \"403 Response\",\n \"401\": \"401 Response\",\n \"409\": \"409 Response\",\n \"429\": \"429 Response\",\n \"503\": \"503 Response\",\n \"504\": \"504 Response\",\n \"400\": \"This schema can be expected for 4xx 'Malformed request.' errors\",\n \"500\": \"This schema can be expected for 5xx 'A server error occurred.' errors\"\n}\n```\n\n- Tags: Actions, Inputs\n- Security: [{\"OAuth\": [\"zap:write\"]}]\n\n## Example\n\n```http\nPOST /v2/actions/{action_id}/inputs HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "POST /v2/actions/{action_id}/inputs", "signature": "POST /v2/actions/{action_id}/inputs", "aliases": [], "flags": [], "args": [{"name": "action_id", "in": "path", "required": true, "type": "string", "description": "An Action ID, as provided by the `/actions` endpoint."}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["actions", "api", "openapi"], "related": [], "meta": {"method": "POST", "path": "/v2/actions/{action_id}/inputs", "spec": "workflow-api-schema.json", "api_title": "Partner API", "servers": ["https://api.zapier.com"], "request_schema": {"$ref": "#/components/schemas/ListInputFieldsRequest"}, "responses": {"200": "", "403": "403 Response", "401": "401 Response", "409": "409 Response", "429": "429 Response", "503": "503 Response", "504": "504 Response", "400": "This schema can be expected for 4xx 'Malformed request.' errors", "500": "This schema can be expected for 5xx 'A server error occurred.' errors"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:get-choices", "kind": "api_function", "key": "get-choices", "title": "POST /v2/actions/{action_id}/inputs/{input_id}/choices — Get Choices", "summary": "Get Choices", "body": "# `get-choices`\n\n> Get Choices\n\n## High-level description\n\nGet the possible values for a `SELECT` Input Field.\n\n#### When using OAuth\n\nThis endpoint requires the `zap` OAuth scope.\n\n## Internals\n\n`POST https://api.zapier.com/v2/actions/{action_id}/inputs/{input_id}/choices` from **Partner API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n action_id: string; // in path — An Action ID, as provided by the `/actions` endpoint.\n input_id: string; // in path — An Input Field ID, as provided by the `/inputs` endpoint.\n page?: string; // in query — The page of choices to return, defaults to the first\n body?: ChoiceRequest; // request JSON\n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"\",\n \"403\": \"403 Response\",\n \"401\": \"401 Response\",\n \"409\": \"409 Response\",\n \"429\": \"429 Response\",\n \"503\": \"503 Response\",\n \"504\": \"504 Response\",\n \"400\": \"This schema can be expected for 4xx 'Malformed request.' errors\",\n \"500\": \"This schema can be expected for 5xx 'A server error occurred.' errors\"\n}\n```\n\n- Tags: Actions, Inputs\n- Security: [{\"OAuth\": [\"zap\"]}]\n\n## Example\n\n```http\nPOST /v2/actions/{action_id}/inputs/{input_id}/choices HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "POST /v2/actions/{action_id}/inputs/{input_id}/choices", "signature": "POST /v2/actions/{action_id}/inputs/{input_id}/choices", "aliases": [], "flags": [], "args": [{"name": "action_id", "in": "path", "required": true, "type": "string", "description": "An Action ID, as provided by the `/actions` endpoint."}, {"name": "input_id", "in": "path", "required": true, "type": "string", "description": "An Input Field ID, as provided by the `/inputs` endpoint."}, {"name": "page", "in": "query", "required": false, "type": "string", "description": "The page of choices to return, defaults to the first"}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["actions", "api", "openapi"], "related": [], "meta": {"method": "POST", "path": "/v2/actions/{action_id}/inputs/{input_id}/choices", "spec": "workflow-api-schema.json", "api_title": "Partner API", "servers": ["https://api.zapier.com"], "request_schema": {"$ref": "#/components/schemas/ChoiceRequest"}, "responses": {"200": "", "403": "403 Response", "401": "401 Response", "409": "409 Response", "429": "429 Response", "503": "503 Response", "504": "504 Response", "400": "This schema can be expected for 4xx 'Malformed request.' errors", "500": "This schema can be expected for 5xx 'A server error occurred.' errors"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:get-fields-outputs", "kind": "api_function", "key": "get-fields-outputs", "title": "POST /v2/actions/{action_id}/outputs — Get Output Fields", "summary": "Get Output Fields", "body": "# `get-fields-outputs`\n\n> Get Output Fields\n\n## High-level description\n\nGet the Output Fields for a particular Action, using the provided authentication and inputs.\n\n#### When using OAuth\n\nThis endpoint requires the `zap:write` OAuth scope.\n\n## Internals\n\n`POST https://api.zapier.com/v2/actions/{action_id}/outputs` from **Partner API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n action_id: string; // in path — An Action ID, as provided by the `/actions` endpoint.\n body?: ListOutputFieldsRequest; // request JSON\n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"\",\n \"403\": \"403 Response\",\n \"401\": \"401 Response\",\n \"409\": \"409 Response\",\n \"429\": \"429 Response\",\n \"503\": \"503 Response\",\n \"504\": \"504 Response\",\n \"400\": \"This schema can be expected for 4xx 'Malformed request.' errors\",\n \"500\": \"This schema can be expected for 5xx 'A server error occurred.' errors\"\n}\n```\n\n- Tags: Actions, Outputs\n- Security: [{\"OAuth\": [\"zap:write\"]}]\n\n## Example\n\n```http\nPOST /v2/actions/{action_id}/outputs HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "POST /v2/actions/{action_id}/outputs", "signature": "POST /v2/actions/{action_id}/outputs", "aliases": [], "flags": [], "args": [{"name": "action_id", "in": "path", "required": true, "type": "string", "description": "An Action ID, as provided by the `/actions` endpoint."}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["actions", "api", "openapi"], "related": [], "meta": {"method": "POST", "path": "/v2/actions/{action_id}/outputs", "spec": "workflow-api-schema.json", "api_title": "Partner API", "servers": ["https://api.zapier.com"], "request_schema": {"$ref": "#/components/schemas/ListOutputFieldsRequest"}, "responses": {"200": "", "403": "403 Response", "401": "401 Response", "409": "409 Response", "429": "429 Response", "503": "503 Response", "504": "504 Response", "400": "This schema can be expected for 4xx 'Malformed request.' errors", "500": "This schema can be expected for 5xx 'A server error occurred.' errors"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:test-action", "kind": "api_function", "key": "test-action", "title": "POST /v2/actions/{action_id}/test — Step Test", "summary": "Step Test", "body": "# `test-action`\n\n> Step Test\n\n## High-level description\n\nTests the action (step) in the third party api, using the provided authentication and inputs.\n\n#### When using OAuth\n\nThis endpoint requires the `zap:write` OAuth scope.\n\n## Internals\n\n`POST https://api.zapier.com/v2/actions/{action_id}/test` from **Partner API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n action_id: string; // in path — An Action ID, as provided by the `/actions` endpoint.\n body?: ActionTestRequest; // request JSON\n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"\",\n \"403\": \"403 Response\",\n \"401\": \"401 Response\",\n \"409\": \"409 Response\",\n \"429\": \"429 Response\",\n \"503\": \"503 Response\",\n \"504\": \"504 Response\",\n \"400\": \"This schema can be expected for 4xx 'Malformed request.' errors\",\n \"500\": \"This schema can be expected for 5xx 'A server error occurred.' errors\"\n}\n```\n\n- Tags: Actions\n- Security: [{\"OAuth\": [\"zap:write\"]}]\n\n## Example\n\n```http\nPOST /v2/actions/{action_id}/test HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "POST /v2/actions/{action_id}/test", "signature": "POST /v2/actions/{action_id}/test", "aliases": [], "flags": [], "args": [{"name": "action_id", "in": "path", "required": true, "type": "string", "description": "An Action ID, as provided by the `/actions` endpoint."}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["actions", "api", "openapi"], "related": [], "meta": {"method": "POST", "path": "/v2/actions/{action_id}/test", "spec": "workflow-api-schema.json", "api_title": "Partner API", "servers": ["https://api.zapier.com"], "request_schema": {"$ref": "#/components/schemas/ActionTestRequest"}, "responses": {"200": "", "403": "403 Response", "401": "401 Response", "409": "409 Response", "429": "429 Response", "503": "503 Response", "504": "504 Response", "400": "This schema can be expected for 4xx 'Malformed request.' errors", "500": "This schema can be expected for 5xx 'A server error occurred.' errors"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:get-v2-apps", "kind": "api_function", "key": "get-v2-apps", "title": "GET /v2/apps — Get Apps v2", "summary": "Get Apps v2", "body": "# `get-v2-apps`\n\n> Get Apps v2\n\n## High-level description\n\nThis endpoint returns a list of apps sorted by popularity.\n\n#### When using Client ID\n\nSimply providing a client ID query parameter is sufficient. If an Authorization header is present, it will be used instead.\n\n#### When using OAuth\n\nThis endpoint requires the `zap` OAuth scope.\n\n## Internals\n\n`GET https://api.zapier.com/v2/apps` from **Partner API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n category?: string; // in query — Categories that apps must have in order to be returned in the response. \nThe full list of valid cate\n ids?: string; // in query — Parameter to restrict the results to apps whose ID matches those in the provided comma-separated val\n limit?: integer; // in query — Used for paginating results. Specifies the maximum number of items to return per page. If this value\n offset?: integer; // in query — Used for paginating results. Specifies the offset to use.\n query?: string; // in query — Parameter to limit the results to apps whose titles match the provided query.\n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"\",\n \"403\": \"403 Response\",\n \"401\": \"401 Response\",\n \"409\": \"409 Response\",\n \"429\": \"429 Response\",\n \"503\": \"503 Response\",\n \"504\": \"504 Response\",\n \"400\": \"This schema can be expected for 4xx 'Malformed request.' errors\",\n \"500\": \"This schema can be expected for 5xx 'A server error occurred.' errors\"\n}\n```\n\n- Tags: Apps\n- Security: [{\"OAuth\": [\"zap\"]}, {\"ClientIDAuthentication\": []}]\n\n## Example\n\n```http\nGET /v2/apps HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "GET /v2/apps", "signature": "GET /v2/apps", "aliases": [], "flags": [], "args": [{"name": "category", "in": "query", "required": false, "type": "string", "description": "Categories that apps must have in order to be returned in the response. \nThe full list of valid categories can be retrieved using the `category` endpoint, detailed [here](https://platform.zapier.com/embed/partner-api#get-v1categories)."}, {"name": "ids", "in": "query", "required": false, "type": "string", "description": "Parameter to restrict the results to apps whose ID matches those in the provided comma-separated value. Cannot be combined with `category`."}, {"name": "limit", "in": "query", "required": false, "type": "integer", "description": "Used for paginating results. Specifies the maximum number of items to return per page. If this value is not set, it defaults to 10."}, {"name": "offset", "in": "query", "required": false, "type": "integer", "description": "Used for paginating results. Specifies the offset to use."}, {"name": "query", "in": "query", "required": false, "type": "string", "description": "Parameter to limit the results to apps whose titles match the provided query."}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "apps", "openapi"], "related": [], "meta": {"method": "GET", "path": "/v2/apps", "spec": "workflow-api-schema.json", "api_title": "Partner API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"200": "", "403": "403 Response", "401": "401 Response", "409": "409 Response", "429": "429 Response", "503": "503 Response", "504": "504 Response", "400": "This schema can be expected for 4xx 'Malformed request.' errors", "500": "This schema can be expected for 5xx 'A server error occurred.' errors"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:get-authentications", "kind": "api_function", "key": "get-authentications", "title": "GET /v2/authentications — Get Authentications", "summary": "Get Authentications", "body": "# `get-authentications`\n\n> Get Authentications\n\n## High-level description\n\nFetch the available Authentications for the provided App. This will only return Authentications that are owned by the user and not those that are shared with them, since it's not possible to create Zaps with Authentications you don't own.\n\n#### When using OAuth\n\nThis endpoint requires the `connection:read` OAuth scope.\n\n## Internals\n\n`GET https://api.zapier.com/v2/authentications` from **Partner API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n app: string; // in query — An App identifier: a canonical App ID (UUID) or an app key\n limit?: integer; // in query — Used for paginating results. Specifies the maximum number of items to return per page. If this value\n offset?: integer; // in query — Used for paginating results. Specifies the offset to use.\n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"\",\n \"403\": \"403 Response\",\n \"401\": \"401 Response\",\n \"409\": \"409 Response\",\n \"429\": \"429 Response\",\n \"503\": \"503 Response\",\n \"504\": \"504 Response\",\n \"400\": \"This schema can be expected for 4xx 'Malformed request.' errors\",\n \"500\": \"This schema can be expected for 5xx 'A server error occurred.' errors\"\n}\n```\n\n- Tags: Authentications\n- Security: [{\"OAuth\": [\"connection:read\"]}]\n\n## Example\n\n```http\nGET /v2/authentications HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "GET /v2/authentications", "signature": "GET /v2/authentications", "aliases": [], "flags": [], "args": [{"name": "app", "in": "query", "required": true, "type": "string", "description": "An App identifier: a canonical App ID (UUID) or an app key"}, {"name": "limit", "in": "query", "required": false, "type": "integer", "description": "Used for paginating results. Specifies the maximum number of items to return per page. If this value is not set, it defaults to 10."}, {"name": "offset", "in": "query", "required": false, "type": "integer", "description": "Used for paginating results. Specifies the offset to use."}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "authentications", "openapi"], "related": [], "meta": {"method": "GET", "path": "/v2/authentications", "spec": "workflow-api-schema.json", "api_title": "Partner API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"200": "", "403": "403 Response", "401": "401 Response", "409": "409 Response", "429": "429 Response", "503": "503 Response", "504": "504 Response", "400": "This schema can be expected for 4xx 'Malformed request.' errors", "500": "This schema can be expected for 5xx 'A server error occurred.' errors"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:create-authentication", "kind": "api_function", "key": "create-authentication", "title": "POST /v2/authentications — Create Authentication", "summary": "Create Authentication", "body": "# `create-authentication`\n\n> Create Authentication\n\n## High-level description\n\nCreates a new Authentication for the provided App. See our Adding an Authentication guide to get started.\n\n#### When using OAuth\n\nThis endpoint requires the `connection:write` OAuth scope.\n\n## Internals\n\n`POST https://api.zapier.com/v2/authentications` from **Partner API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n body?: AuthenticationCreateRequest; // request JSON\n};\n```\n\n## Outputs\n\n```json\n{\n \"201\": \"\",\n \"403\": \"403 Response\",\n \"401\": \"401 Response\",\n \"409\": \"409 Response\",\n \"429\": \"429 Response\",\n \"503\": \"503 Response\",\n \"504\": \"504 Response\",\n \"400\": \"This schema can be expected for 4xx 'Malformed request.' errors\",\n \"500\": \"This schema can be expected for 5xx 'A server error occurred.' errors\"\n}\n```\n\n- Tags: Authentications\n- Security: [{\"OAuth\": [\"connection:write\"]}]\n\n## Example\n\n```http\nPOST /v2/authentications HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "POST /v2/authentications", "signature": "POST /v2/authentications", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "authentications", "openapi"], "related": [], "meta": {"method": "POST", "path": "/v2/authentications", "spec": "workflow-api-schema.json", "api_title": "Partner API", "servers": ["https://api.zapier.com"], "request_schema": {"$ref": "#/components/schemas/AuthenticationCreateRequest"}, "responses": {"201": "", "403": "403 Response", "401": "401 Response", "409": "409 Response", "429": "429 Response", "503": "503 Response", "504": "504 Response", "400": "This schema can be expected for 4xx 'Malformed request.' errors", "500": "This schema can be expected for 5xx 'A server error occurred.' errors"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:delete-authentication", "kind": "api_function", "key": "delete-authentication", "title": "DELETE /v2/authentications/{authentication_id} — Delete Authentication", "summary": "Delete Authentication", "body": "# `delete-authentication`\n\n> Delete Authentication\n\n## High-level description\n\nDeletes the Authentication with the provided ID. Once deleted, the Authentication can no longer be used and will no longer be returned by the `/authentications` endpoint. Returns a `404` if the Authentication does not exist or is not owned by the user.\n\n#### When using OAuth\n\nThis endpoint requires the `connection:delete` OAuth scope.\n\n## Internals\n\n`DELETE https://api.zapier.com/v2/authentications/{authentication_id}` from **Partner API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n authentication_id: string; // in path — An Authentication ID, as provided by the `/authentications` endpoint.\n};\n```\n\n## Outputs\n\n```json\n{\n \"204\": \"No Content\",\n \"403\": \"403 Response\",\n \"401\": \"401 Response\",\n \"409\": \"409 Response\",\n \"429\": \"429 Response\",\n \"503\": \"503 Response\",\n \"504\": \"504 Response\",\n \"400\": \"This schema can be expected for 4xx 'Malformed request.' errors\",\n \"500\": \"This schema can be expected for 5xx 'A server error occurred.' errors\"\n}\n```\n\n- Tags: Authentications\n- Security: [{\"OAuth\": [\"connection:delete\"]}]\n\n## Example\n\n```http\nDELETE /v2/authentications/{authentication_id} HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "DELETE /v2/authentications/{authentication_id}", "signature": "DELETE /v2/authentications/{authentication_id}", "aliases": [], "flags": [], "args": [{"name": "authentication_id", "in": "path", "required": true, "type": "string", "description": "An Authentication ID, as provided by the `/authentications` endpoint."}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "authentications", "openapi"], "related": [], "meta": {"method": "DELETE", "path": "/v2/authentications/{authentication_id}", "spec": "workflow-api-schema.json", "api_title": "Partner API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"204": "No Content", "403": "403 Response", "401": "401 Response", "409": "409 Response", "429": "429 Response", "503": "503 Response", "504": "504 Response", "400": "This schema can be expected for 4xx 'Malformed request.' errors", "500": "This schema can be expected for 5xx 'A server error occurred.' errors"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:v2_authorize_list", "kind": "api_function", "key": "v2_authorize_list", "title": "GET /v2/authorize — Create Account", "summary": "Create Account", "body": "# `v2_authorize_list`\n\n> Create Account\n\n## High-level description\n\nCreate a new user and obtain an access token. See our Quick Account Creation guide to get started.\n\n## Internals\n\n`GET https://api.zapier.com/v2/authorize` from **Partner API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n client_id: string; // in query — Your application Client ID.\n redirect_uri: string; // in query — The page the user will be redirect to after OAuth flow.\n referer?: string; // in query — \n response_type: string; // in query — Only OAuth response type `code` is supported\n scope: string; // in query — Space (`%20`) separated values\n sign_up_email?: string; // in query — Email of the user signing up.\n sign_up_first_name?: string; // in query — First name of the user signing up.\n sign_up_last_name?: string; // in query — Last name of the user signing up.\n utm_campaign?: string; // in query — \n utm_content?: string; // in query — \n utm_medium?: string; // in query — \n utm_source?: string; // in query — \n};\n```\n\n## Outputs\n\n```json\n{\n \"302\": \"Redirect to authorization URL\",\n \"403\": \"403 Response\",\n \"401\": \"401 Response\",\n \"409\": \"409 Response\",\n \"429\": \"429 Response\",\n \"503\": \"503 Response\",\n \"504\": \"504 Response\",\n \"400\": \"This schema can be expected for 4xx 'Malformed request.' errors\",\n \"500\": \"This schema can be expected for 5xx 'A server error occurred.' errors\"\n}\n```\n\n- Tags: Accounts\n- Security: [{\"ClientIDAuthentication\": []}]\n\n## Example\n\n```http\nGET /v2/authorize HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "GET /v2/authorize", "signature": "GET /v2/authorize", "aliases": [], "flags": [], "args": [{"name": "client_id", "in": "query", "required": true, "type": "string", "description": "Your application Client ID."}, {"name": "redirect_uri", "in": "query", "required": true, "type": "string", "description": "The page the user will be redirect to after OAuth flow."}, {"name": "referer", "in": "query", "required": false, "type": "string", "description": ""}, {"name": "response_type", "in": "query", "required": true, "type": "string", "description": "Only OAuth response type `code` is supported"}, {"name": "scope", "in": "query", "required": true, "type": "string", "description": "Space (`%20`) separated values"}, {"name": "sign_up_email", "in": "query", "required": false, "type": "string", "description": "Email of the user signing up."}, {"name": "sign_up_first_name", "in": "query", "required": false, "type": "string", "description": "First name of the user signing up."}, {"name": "sign_up_last_name", "in": "query", "required": false, "type": "string", "description": "Last name of the user signing up."}, {"name": "utm_campaign", "in": "query", "required": false, "type": "string", "description": ""}, {"name": "utm_content", "in": "query", "required": false, "type": "string", "description": ""}, {"name": "utm_medium", "in": "query", "required": false, "type": "string", "description": ""}, {"name": "utm_source", "in": "query", "required": false, "type": "string", "description": ""}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["accounts", "api", "openapi"], "related": [], "meta": {"method": "GET", "path": "/v2/authorize", "spec": "workflow-api-schema.json", "api_title": "Partner API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"302": "Redirect to authorization URL", "403": "403 Response", "401": "401 Response", "409": "409 Response", "429": "429 Response", "503": "503 Response", "504": "504 Response", "400": "This schema can be expected for 4xx 'Malformed request.' errors", "500": "This schema can be expected for 5xx 'A server error occurred.' errors"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:create-zap-guess", "kind": "api_function", "key": "create-zap-guess", "title": "POST /v2/guess — Guess a Zap Beta", "summary": "Guess a Zap Beta", "body": "# `create-zap-guess`\n\n> Guess a Zap Beta\n\n## High-level description\n\nThis endpoint returns a suggested Zap and pre-filled URL to Zapier from a given prompt.\n\n## Internals\n\n`POST https://api.zapier.com/v2/guess` from **Partner API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n client_id: string; // in query — See our authentication documentation for how to find your client ID\n body?: ZapGuesserRequest; // request JSON\n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"\",\n \"403\": \"403 Response\",\n \"401\": \"401 Response\",\n \"409\": \"409 Response\",\n \"429\": \"429 Response\",\n \"503\": \"503 Response\",\n \"504\": \"504 Response\",\n \"400\": \"This schema can be expected for 400 'Malformed request.' errors\",\n \"500\": \"This schema can be expected for 5xx 'A server error occurred.' errors\"\n}\n```\n\n- Tags: Zaps\n- Security: []\n\n## Example\n\n```http\nPOST /v2/guess HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "POST /v2/guess", "signature": "POST /v2/guess", "aliases": [], "flags": [], "args": [{"name": "client_id", "in": "query", "required": true, "type": "string", "description": "See our authentication documentation for how to find your client ID"}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "openapi", "zaps"], "related": [], "meta": {"method": "POST", "path": "/v2/guess", "spec": "workflow-api-schema.json", "api_title": "Partner API", "servers": ["https://api.zapier.com"], "request_schema": {"$ref": "#/components/schemas/ZapGuesserRequest"}, "responses": {"200": "", "403": "403 Response", "401": "401 Response", "409": "409 Response", "429": "429 Response", "503": "503 Response", "504": "504 Response", "400": "This schema can be expected for 400 'Malformed request.' errors", "500": "This schema can be expected for 5xx 'A server error occurred.' errors"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:v2-whitelabel-apps-list", "kind": "api_function", "key": "v2-whitelabel-apps-list", "title": "GET /v2/whitelabel/apps — Get Whitelabel Apps v2", "summary": "Get Whitelabel Apps v2", "body": "# `v2-whitelabel-apps-list`\n\n> Get Whitelabel Apps v2\n\n## High-level description\n\nThis endpoint returns a list of apps available for whitelabel connection. It is only for customers enrolled in the Zapier Whitelabel program. All others likely want the `Get Apps` endpoint instead.\n\n## Internals\n\n`GET https://api.zapier.com/v2/whitelabel/apps` from **Partner API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n category?: string; // in query — Filter apps by category slug.\n limit?: number; // in query — Limit the number of apps returned.\n offset?: number; // in query — The number of apps to skip before beginning to return results.\n search?: string; // in query — Case-insensitive search to filter apps by title.\n};\n```\n\n## Outputs\n\n```json\n{\n \"403\": \"403 Response\",\n \"401\": \"401 Response\",\n \"409\": \"409 Response\",\n \"429\": \"429 Response\",\n \"503\": \"503 Response\",\n \"504\": \"504 Response\",\n \"400\": \"This schema can be expected for 4xx 'Malformed request.' errors\",\n \"500\": \"This schema can be expected for 5xx 'A server error occurred.' errors\",\n \"200\": \"\"\n}\n```\n\n- Tags: Apps, Experimental\n- Security: []\n\n## Example\n\n```http\nGET /v2/whitelabel/apps HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "GET /v2/whitelabel/apps", "signature": "GET /v2/whitelabel/apps", "aliases": [], "flags": [], "args": [{"name": "category", "in": "query", "required": false, "type": "string", "description": "Filter apps by category slug."}, {"name": "limit", "in": "query", "required": false, "type": "number", "description": "Limit the number of apps returned."}, {"name": "offset", "in": "query", "required": false, "type": "number", "description": "The number of apps to skip before beginning to return results."}, {"name": "search", "in": "query", "required": false, "type": "string", "description": "Case-insensitive search to filter apps by title."}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "apps", "openapi"], "related": [], "meta": {"method": "GET", "path": "/v2/whitelabel/apps", "spec": "workflow-api-schema.json", "api_title": "Partner API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"403": "403 Response", "401": "401 Response", "409": "409 Response", "429": "429 Response", "503": "503 Response", "504": "504 Response", "400": "This schema can be expected for 4xx 'Malformed request.' errors", "500": "This schema can be expected for 5xx 'A server error occurred.' errors", "200": ""}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:get-zap-runs", "kind": "api_function", "key": "get-zap-runs", "title": "GET /v2/zap-runs — Get Zap Runs", "summary": "Get Zap Runs", "body": "# `get-zap-runs`\n\n> Get Zap Runs\n\n## High-level description\n\nThis endpoint returns runs for the specified Zaps and provides basic yet essential details about their execution. As the initial version, it serves foundational information, with plans for continuous enhancement to expand its capabilities and improve data output over time.\n\n#### When using OAuth\n\nThis endpoint requires the `zap:runs` OAuth scope.\n\n## Internals\n\n`GET https://api.zapier.com/v2/zap-runs` from **Partner API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n from_date?: string; // in query — Filter Zap runs that occurred on or after this date. If not provided, the results default to Zap run\n limit?: integer; // in query — Used for paginating results. Specifies the maximum number of items to return per page. If this value\n offset?: integer; // in query — Used for paginating results. Specifies the offset to use.\n search?: string; // in query — Performs a text search against the zap_title, data_in, and data_out fields, returning only zap runs \n statuses?: Array<string>; // in query — Accepts one or more status values separated by comma, enabling the filtering of zap runs based on th\n to_date?: string; // in query — Filter Zap runs that occurred before this date.\n zap_id?: integer; // in query — Find Zap runs for the specified Zap ID.\n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"\",\n \"403\": \"403 Response\",\n \"401\": \"401 Response\",\n \"409\": \"409 Response\",\n \"429\": \"429 Response\",\n \"503\": \"503 Response\",\n \"504\": \"504 Response\",\n \"400\": \"This schema can be expected for 4xx 'Malformed request.' errors\",\n \"500\": \"This schema can be expected for 5xx 'A server error occurred.' errors\"\n}\n```\n\n- Tags: Experimental, Zaps\n- Security: [{\"OAuth\": [\"zap:runs\"]}]\n\n## Example\n\n```http\nGET /v2/zap-runs HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "GET /v2/zap-runs", "signature": "GET /v2/zap-runs", "aliases": [], "flags": [], "args": [{"name": "from_date", "in": "query", "required": false, "type": "string", "description": "Filter Zap runs that occurred on or after this date. If not provided, the results default to Zap runs from the last 30 days."}, {"name": "limit", "in": "query", "required": false, "type": "integer", "description": "Used for paginating results. Specifies the maximum number of items to return per page. If this value is not set, it defaults to 10."}, {"name": "offset", "in": "query", "required": false, "type": "integer", "description": "Used for paginating results. Specifies the offset to use."}, {"name": "search", "in": "query", "required": false, "type": "string", "description": "Performs a text search against the zap_title, data_in, and data_out fields, returning only zap runs that match the specified keywords."}, {"name": "statuses", "in": "query", "required": false, "type": "Array<string>", "description": "Accepts one or more status values separated by comma, enabling the filtering of zap runs based on the specified status or statuses provided."}, {"name": "to_date", "in": "query", "required": false, "type": "string", "description": "Filter Zap runs that occurred before this date."}, {"name": "zap_id", "in": "query", "required": false, "type": "integer", "description": "Find Zap runs for the specified Zap ID."}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "experimental", "openapi"], "related": [], "meta": {"method": "GET", "path": "/v2/zap-runs", "spec": "workflow-api-schema.json", "api_title": "Partner API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"200": "", "403": "403 Response", "401": "401 Response", "409": "409 Response", "429": "429 Response", "503": "503 Response", "504": "504 Response", "400": "This schema can be expected for 4xx 'Malformed request.' errors", "500": "This schema can be expected for 5xx 'A server error occurred.' errors"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:get-v2-zaps", "kind": "api_function", "key": "get-v2-zaps", "title": "GET /v2/zaps — Get Zaps v2", "summary": "Get Zaps v2", "body": "# `get-v2-zaps`\n\n> Get Zaps v2\n\n## High-level description\n\nThis endpoint returns a list of Zaps for the authenticated Zapier user.\n\nThe `expand` array can be used to expand selected fields into full objects in the response. Inputs with keys can\nalso be passed to filter Zaps by certain criteria.\n\n**Scope Selection:**\n- Use `zap` if you have a Zapier integration and wish to get only Zaps using your integration.\n- Use `zap:all` to get all of the user's Zaps.\n- Use `zap:account:all` to get all of the Zaps the user has access to in their account.\n\n#### When using OAuth\n\nThis endpoint requires the `zap`, `zap:all`, or `zap:account:all` OAuth scopes.\n\n## Internals\n\n`GET https://api.zapier.com/v2/zaps` from **Partner API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n expand?: string; // in query — A comma separated list of Zap fields that should be expanded from ids to full objects in the respons\n include_shared?: boolean; // in query — If true, all Zaps that are shared with the user, rather than only those owned by them, are returned.\n inputs?: string; // in query — You may pass inputs[KEY]=VALUE1,VALUE2 to filter for Zaps that contain those settings. Keys are defi\n limit?: integer; // in query — Used for paginating results. Specifies the maximum number of items to return per page. If this value\n offset?: integer; // in query — Used for paginating results. Specifies the offset to use.\n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"\",\n \"403\": \"403 Response\",\n \"401\": \"401 Response\",\n \"409\": \"409 Response\",\n \"429\": \"429 Response\",\n \"503\": \"503 Response\",\n \"504\": \"504 Response\",\n \"400\": \"This schema can be expected for 4xx 'Malformed request.' errors\",\n \"500\": \"This schema can be expected for 5xx 'A server error occurred.' errors\"\n}\n```\n\n- Tags: Zaps\n- Security: [{\"OAuth\": [\"zap\", \"zap:all\"]}]\n\n## Example\n\n```http\nGET /v2/zaps HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "GET /v2/zaps", "signature": "GET /v2/zaps", "aliases": [], "flags": [], "args": [{"name": "expand", "in": "query", "required": false, "type": "string", "description": "A comma separated list of Zap fields that should be expanded from ids to full objects in the response. Fields that may not be expanded will remain as ids."}, {"name": "include_shared", "in": "query", "required": false, "type": "boolean", "description": "If true, all Zaps that are shared with the user, rather than only those owned by them, are returned. If the zap:account:all scope is not present this has no effect."}, {"name": "inputs", "in": "query", "required": false, "type": "string", "description": "You may pass inputs[KEY]=VALUE1,VALUE2 to filter for Zaps that contain those settings. Keys are defined by your app on the developer platform."}, {"name": "limit", "in": "query", "required": false, "type": "integer", "description": "Used for paginating results. Specifies the maximum number of items to return per page. If this value is not set, it defaults to 10."}, {"name": "offset", "in": "query", "required": false, "type": "integer", "description": "Used for paginating results. Specifies the offset to use."}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "openapi", "zaps"], "related": [], "meta": {"method": "GET", "path": "/v2/zaps", "spec": "workflow-api-schema.json", "api_title": "Partner API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"200": "", "403": "403 Response", "401": "401 Response", "409": "409 Response", "429": "429 Response", "503": "503 Response", "504": "504 Response", "400": "This schema can be expected for 4xx 'Malformed request.' errors", "500": "This schema can be expected for 5xx 'A server error occurred.' errors"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:post-zaps", "kind": "api_function", "key": "post-zaps", "title": "POST /v2/zaps — Create a Zap", "summary": "Create a Zap", "body": "# `post-zaps`\n\n> Create a Zap\n\n## High-level description\n\nThis URL creates a Zap based on the given steps and title.\n\n#### When using OAuth\n\nThis endpoint requires the `zap:write`, or `zap:all` OAuth scopes.\n\n## Internals\n\n`POST https://api.zapier.com/v2/zaps` from **Partner API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n expand?: string; // in query — A comma separated list of Zap fields that should be expanded from ids to full objects in the respons\n body?: ZapRequest; // request JSON\n};\n```\n\n## Outputs\n\n```json\n{\n \"201\": \"\",\n \"403\": \"403 Response\",\n \"401\": \"401 Response\",\n \"409\": \"409 Response\",\n \"429\": \"429 Response\",\n \"503\": \"503 Response\",\n \"504\": \"504 Response\",\n \"400\": \"This schema can be expected for 4xx 'Malformed request.' errors\",\n \"500\": \"This schema can be expected for 5xx 'A server error occurred.' errors\"\n}\n```\n\n- Tags: Zaps\n- Security: [{\"OAuth\": [\"zap:write\", \"zap:all\"]}]\n\n## Example\n\n```http\nPOST /v2/zaps HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "POST /v2/zaps", "signature": "POST /v2/zaps", "aliases": [], "flags": [], "args": [{"name": "expand", "in": "query", "required": false, "type": "string", "description": "A comma separated list of Zap fields that should be expanded from ids to full objects in the response. Fields that may not be expanded will remain as ids."}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "openapi", "zaps"], "related": [], "meta": {"method": "POST", "path": "/v2/zaps", "spec": "workflow-api-schema.json", "api_title": "Partner API", "servers": ["https://api.zapier.com"], "request_schema": {"$ref": "#/components/schemas/ZapRequest"}, "responses": {"201": "", "403": "403 Response", "401": "401 Response", "409": "409 Response", "429": "429 Response", "503": "503 Response", "504": "504 Response", "400": "This schema can be expected for 4xx 'Malformed request.' errors", "500": "This schema can be expected for 5xx 'A server error occurred.' errors"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:patch-zaps", "kind": "api_function", "key": "patch-zaps", "title": "PATCH /v2/zaps/{id} — Edit a Zap", "summary": "Edit a Zap", "body": "# `patch-zaps`\n\n> Edit a Zap\n\n## High-level description\n\nEdits a Zap on behalf of an end user. Accepts `title` and/or `steps`; any provided `steps` fully replace the Zap's existing step list. Editing `steps` publishes a new version and enables the Zap, even if it was previously paused. A `title`-only edit does not change whether the Zap is paused or enabled.\n\n#### When using OAuth\n\nThis endpoint requires the `zap:update` OAuth scope.\n\n## Internals\n\n`PATCH https://api.zapier.com/v2/zaps/{id}` from **Partner API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n id: string; // in path — The Zap ID as returned by GET /v2/zaps or POST /v2/zaps.\n body?: PatchedZapPatchRequest; // request JSON\n};\n```\n\n## Outputs\n\n```json\n{\n \"200\": \"\",\n \"403\": \"403 Response\",\n \"401\": \"401 Response\",\n \"409\": \"409 Response\",\n \"429\": \"429 Response\",\n \"503\": \"503 Response\",\n \"504\": \"504 Response\",\n \"400\": \"This schema can be expected for 4xx 'Malformed request.' errors\",\n \"500\": \"This schema can be expected for 5xx 'A server error occurred.' errors\"\n}\n```\n\n- Tags: Zaps\n- Security: [{\"OAuth\": [\"zap:update\"]}]\n\n## Example\n\n```http\nPATCH /v2/zaps/{id} HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "PATCH /v2/zaps/{id}", "signature": "PATCH /v2/zaps/{id}", "aliases": [], "flags": [], "args": [{"name": "id", "in": "path", "required": true, "type": "string", "description": "The Zap ID as returned by GET /v2/zaps or POST /v2/zaps."}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "openapi", "zaps"], "related": [], "meta": {"method": "PATCH", "path": "/v2/zaps/{id}", "spec": "workflow-api-schema.json", "api_title": "Partner API", "servers": ["https://api.zapier.com"], "request_schema": {"$ref": "#/components/schemas/PatchedZapPatchRequest"}, "responses": {"200": "", "403": "403 Response", "401": "401 Response", "409": "409 Response", "429": "429 Response", "503": "503 Response", "504": "504 Response", "400": "This schema can be expected for 4xx 'Malformed request.' errors", "500": "This schema can be expected for 5xx 'A server error occurred.' errors"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:delete-zaps", "kind": "api_function", "key": "delete-zaps", "title": "DELETE /v2/zaps/{id} — Delete a Zap", "summary": "Delete a Zap", "body": "# `delete-zaps`\n\n> Delete a Zap\n\n## High-level description\n\nPermanently deletes a Zap on behalf of an end user. The Zap is stopped and removed from the end user's account. This action cannot be undone.\n\n#### When using OAuth\n\nThis endpoint requires the `zap:delete` OAuth scope.\n\n## Internals\n\n`DELETE https://api.zapier.com/v2/zaps/{id}` from **Partner API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n id: string; // in path — The Zap ID as returned by GET /v2/zaps or POST /v2/zaps.\n};\n```\n\n## Outputs\n\n```json\n{\n \"204\": \"No response body\",\n \"403\": \"403 Response\",\n \"401\": \"401 Response\",\n \"409\": \"409 Response\",\n \"429\": \"429 Response\",\n \"503\": \"503 Response\",\n \"504\": \"504 Response\",\n \"400\": \"This schema can be expected for 4xx 'Malformed request.' errors\",\n \"500\": \"This schema can be expected for 5xx 'A server error occurred.' errors\"\n}\n```\n\n- Tags: Zaps\n- Security: [{\"OAuth\": [\"zap:delete\"]}]\n\n## Example\n\n```http\nDELETE /v2/zaps/{id} HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "DELETE /v2/zaps/{id}", "signature": "DELETE /v2/zaps/{id}", "aliases": [], "flags": [], "args": [{"name": "id", "in": "path", "required": true, "type": "string", "description": "The Zap ID as returned by GET /v2/zaps or POST /v2/zaps."}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "openapi", "zaps"], "related": [], "meta": {"method": "DELETE", "path": "/v2/zaps/{id}", "spec": "workflow-api-schema.json", "api_title": "Partner API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"204": "No response body", "403": "403 Response", "401": "401 Response", "409": "409 Response", "429": "429 Response", "503": "503 Response", "504": "504 Response", "400": "This schema can be expected for 4xx 'Malformed request.' errors", "500": "This schema can be expected for 5xx 'A server error occurred.' errors"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:disable-zaps", "kind": "api_function", "key": "disable-zaps", "title": "POST /v2/zaps/{id}/disable — Disable a Zap", "summary": "Disable a Zap", "body": "# `disable-zaps`\n\n> Disable a Zap\n\n## High-level description\n\nDisables (pauses) a Zap on behalf of an end user without deleting it. Disabling a Zap that is already paused succeeds without making changes.\n\n#### When using OAuth\n\nThis endpoint requires the `zap:pause` OAuth scope.\n\n## Internals\n\n`POST https://api.zapier.com/v2/zaps/{id}/disable` from **Partner API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n id: string; // in path — The Zap ID as returned by GET /v2/zaps or POST /v2/zaps.\n};\n```\n\n## Outputs\n\n```json\n{\n \"204\": \"No response body\",\n \"403\": \"403 Response\",\n \"401\": \"401 Response\",\n \"409\": \"409 Response\",\n \"429\": \"429 Response\",\n \"503\": \"503 Response\",\n \"504\": \"504 Response\",\n \"400\": \"This schema can be expected for 4xx 'Malformed request.' errors\",\n \"500\": \"This schema can be expected for 5xx 'A server error occurred.' errors\"\n}\n```\n\n- Tags: Zaps\n- Security: [{\"OAuth\": [\"zap:pause\"]}]\n\n## Example\n\n```http\nPOST /v2/zaps/{id}/disable HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "POST /v2/zaps/{id}/disable", "signature": "POST /v2/zaps/{id}/disable", "aliases": [], "flags": [], "args": [{"name": "id", "in": "path", "required": true, "type": "string", "description": "The Zap ID as returned by GET /v2/zaps or POST /v2/zaps."}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "openapi", "zaps"], "related": [], "meta": {"method": "POST", "path": "/v2/zaps/{id}/disable", "spec": "workflow-api-schema.json", "api_title": "Partner API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"204": "No response body", "403": "403 Response", "401": "401 Response", "409": "409 Response", "429": "429 Response", "503": "503 Response", "504": "504 Response", "400": "This schema can be expected for 4xx 'Malformed request.' errors", "500": "This schema can be expected for 5xx 'A server error occurred.' errors"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "api_function:enable-zaps", "kind": "api_function", "key": "enable-zaps", "title": "POST /v2/zaps/{id}/enable — Enable a Zap", "summary": "Enable a Zap", "body": "# `enable-zaps`\n\n> Enable a Zap\n\n## High-level description\n\nEnables (unpauses) a Zap on behalf of an end user by re-enabling its current published version. Enabling a Zap that is already running succeeds without making changes.\n\n#### When using OAuth\n\nThis endpoint requires the `zap:pause` OAuth scope.\n\n## Internals\n\n`POST https://api.zapier.com/v2/zaps/{id}/enable` from **Partner API**. Authenticate per spec (OAuth / partner JWT / embed secret). This is a Zapier *public* API — not `z.request` inside a connector.\n\n## Typed inputs\n\n```ts\ntype Input = {\n id: string; // in path — The Zap ID as returned by GET /v2/zaps or POST /v2/zaps.\n};\n```\n\n## Outputs\n\n```json\n{\n \"204\": \"No response body\",\n \"403\": \"403 Response\",\n \"401\": \"401 Response\",\n \"409\": \"409 Response\",\n \"429\": \"429 Response\",\n \"503\": \"503 Response\",\n \"504\": \"504 Response\",\n \"400\": \"This schema can be expected for 4xx 'Malformed request.' errors\",\n \"500\": \"This schema can be expected for 5xx 'A server error occurred.' errors\"\n}\n```\n\n- Tags: Zaps\n- Security: [{\"OAuth\": [\"zap:pause\"]}]\n\n## Example\n\n```http\nPOST /v2/zaps/{id}/enable HTTP/1.1\nHost: api.zapier.com\nAuthorization: Bearer <token>\n```", "usage": "POST /v2/zaps/{id}/enable", "signature": "POST /v2/zaps/{id}/enable", "aliases": [], "flags": [], "args": [{"name": "id", "in": "path", "required": true, "type": "string", "description": "The Zap ID as returned by GET /v2/zaps or POST /v2/zaps."}], "examples": [], "source_url": "https://docs.zapier.com/api-reference", "source_repo": "", "source_path": "", "section": "api-reference", "tags": ["api", "openapi", "zaps"], "related": [], "meta": {"method": "POST", "path": "/v2/zaps/{id}/enable", "spec": "workflow-api-schema.json", "api_title": "Partner API", "servers": ["https://api.zapier.com"], "request_schema": null, "responses": {"204": "No response body", "403": "403 Response", "401": "401 Response", "409": "409 Response", "429": "429 Response", "503": "503 Response", "504": "504 Response", "400": "This schema can be expected for 4xx 'Malformed request.' errors", "500": "This schema can be expected for 5xx 'A server error occurred.' errors"}}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2025/4xx-errors-refreshaccesstoken", "kind": "platform_news", "key": "2025/4xx-errors-refreshAccessToken", "title": "No more manual handling of 4xx errors in refreshAccessToken", "summary": "No more manual handling of 4xx errors in refreshAccessToken", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# No more manual handling of 4xx errors in refreshAccessToken\n\n> We now automatically handle 4xx error responses when refreshing OAuth2 access tokens.\n\n*Effective: 2025-09-08*\n\nWe made a change to how we handle error responses when refreshing OAuth2 access tokens.\n\n## Old behavior\n\nWhen an app gives an error response (status code 4xx or 5xx) while refreshing the OAuth2 access token, Zapier keeps retrying the Zap step indefinitely or until it hits a certain limit, depending on the user's settings.\n\n## New behavior\n\nWhen an app encounter a 4xx error response (except for the ones listed below) while refreshing the access token, Zapier will mark the connect as stale, and send an email telling the user to reconnect.\n\nExceptions: The following 4xx errors often indicate a temporary issue so they still have the same behavior as before:\n\n* 408 (Request Timeout)\n* 409 (Conflict)\n* 423 (Locked)\n* 425 (Too Early)\n* 429 (Too Many Requests)\n\nThis is how Zapier handles a stale connection:\n\n* If the stale connection is used by a trigger step, the trigger polling system will skip polling when the scheduled time comes.\n* If the stale connection is used by an action step, the Zap run will be put on hold until the user reconnects and replays the run.\n\n## What does it mean to you?\n\nYou don't need to handle 4xx error responses in `refreshAccessToken` anymore. For example, you might have been catching 4xx errors in `refreshAccessToken` by enabling `skipThrowForStatus` and throwing `ExpiredAuthError`:\n\n```js theme={null}\nconst refreshAccessToken = async (z, bundle) => {\n const response = await z.request({\n url: \"https://example.com/token/refresh\",\n method: \"POST\",\n body: {\n refresh_token: bundle.authData.refresh_token,\n client_id: process.env.CLIENT_ID,\n client_secret: process.env.CLIENT_SECRET,\n grant_type: \"refresh_token\",\n },\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n skipThrowForStatus: true,\n });\n\n if (response.status >= 400 && response.status < 500) {\n throw new z.errors.ExpiredAuthError(\n \"Authentication issue. Please reconnect.\",\n );\n }\n\n return response.data;\n};\n```\n\nThis is no longer necessary. Now you can simplify your code as follows and let the platform handle it:\n\n```js theme={null}\nconst refreshAccessToken = async (z, bundle) => {\n const response = await z.request({\n url: \"https://example.com/token/refresh\",\n method: \"POST\",\n body: {\n refresh_token: bundle.authData.refresh_token,\n client_id: process.env.CLIENT_ID,\n client_secret: process.env.CLIENT_SECRET,\n grant_type: \"refresh_token\",\n },\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n });\n return response.data;\n};\n```\n\nNo need to upgrade zapier-platform-core; this change is implemented in the Zapier backend.\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2025/4xx-errors-refreshAccessToken", "source_repo": "", "source_path": "", "section": "news", "tags": ["2025", "changelog", "news"], "related": [], "meta": {"year": "2025"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2025/index", "kind": "platform_news", "key": "2025/index", "title": "Platform News in 2025", "summary": "Platform News in 2025", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# Platform News in 2025\n\n<Card title=\"What's changed in v18.0.6\" icon=\"newspaper\" href=\"/integrations/news/2025/v18.0.6\" horizontal>\n Package manager detection from `zapier build`\n\n *Released: 2025-12-24*\n</Card>\n\n<Card title=\"What's changed in v18.0.5\" icon=\"newspaper\" href=\"/integrations/news/2025/v18.0.5\" horizontal>\n A security fix on the CLI.\n\n *Released: 2025-12-10*\n</Card>\n\n<Card title=\"Incident: Unauthorized Access to Zapier NPM Packages\" icon=\"newspaper\" href=\"/integrations/news/2025/npm-package-sec-inc\" horizontal>\n Please review the enclosed list of packages and recommendations for Zapier developers.\n\n *Released: 2025-11-24*\n</Card>\n\n<Card title=\"What's changed in v18.0.1\" icon=\"newspaper\" href=\"/integrations/news/2025/v18.0.1\" horizontal>\n Bug fixes for npx resolution and TypeScript typing for line items.\n\n *Released: 2025-11-05*\n</Card>\n\n<Card title=\"What's changed in v18.0.0\" icon=\"newspaper\" href=\"/integrations/news/2025/v18.0.0\" horizontal>\n Node.js 22 support, new throttling middleware, and a new CLI executable name `zapier-platform`.\n\n *Released: 2025-10-30*\n</Card>\n\n<Card title=\"What's changed in v17.9.1\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.9.1\" horizontal>\n Bug fix for zapier push and dependency updates.\n\n *Released: 2025-10-28*\n</Card>\n\n<Card title=\"Self-serve static IP for private integrations\" icon=\"newspaper\" href=\"/integrations/news/2025/static-ip-self-serve\" horizontal>\n Developers can now enable static IP addresses for private integrations directly in Platform UI without contacting support.\n\n *Released: 2025-10-21*\n</Card>\n\n<Card title=\"Labeled Versions now available in CLI and Platform UI\" icon=\"newspaper\" href=\"/integrations/news/2025/labeled-versions\" horizontal>\n Integration version numbers can now include a label, to enable you to develop and test changes without committing to a [semantic version number](/integrations/manage/versions#version-numbering) until you're ready.\n\n *Released: 2025-10-21*\n</Card>\n\n<Card title=\"What's changed in v17.9.0\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.9.0\" horizontal>\n Bugfix for snapshot flag, improvements for `zapier env`.\n\n *Released: 2025-10-20*\n</Card>\n\n<Card title=\"What's changed in v17.8.0\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.8.0\" horizontal>\n Added flexibility for Search Pagination and cleaning up some dependencies. Zapier push now supports snapshot publishing.\n\n *Released: 2025-10-07*\n</Card>\n\n<Card title=\"Migration UI now supports individual and organization-level migrations\" icon=\"newspaper\" href=\"/integrations/news/2025/organization-user-migration-in-ui\" horizontal>\n Enhanced migration UI with granular control options for individual and organization-level migrations.\n\n *Released: 2025-10-02*\n</Card>\n\n<Card title=\"What's changed in v17.7.2\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.7.2\" horizontal>\n Fixed issues with typing and semver restriction.\n\n *Released: 2025-09-17*\n</Card>\n\n<Card title=\"What's changed in v17.7.1\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.7.1\" horizontal>\n Improved `zapier scaffold`, `zapier init`, `zapier validate`, and `zapier invoke auth`. Also fixed issues with uncensored sensitive information and field grouping schema.\n\n *Released: 2025-09-10*\n</Card>\n\n<Card title=\"No more manual handling of 4xx errors in refreshAccessToken\" icon=\"lightbulb-on\" href=\"/integrations/news/2025/4xx-errors-refreshAccessToken\" horizontal>\n We now automatically handle 4xx error responses when refreshing OAuth2 access tokens.\n\n *Effective: 2025-09-08*\n</Card>\n\n<Card title=\"What's changed in v17.7.0\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.7.0\" horizontal>\n This update lays groundwork for Search Pagination, which will allow Search steps to paginate through results so that the most relevant results can be returned. However, this is not yet supported by any Zapier products.\n\n *Released: 2025-08-22*\n</Card>\n\n<Card title=\"What's changed in v17.6.0\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.6.0\" horizontal>\n Global `console` object and account filtering for `zapier canary`.\n\n *Released: 2025-08-11*\n</Card>\n\n<Card title=\"What's changed in v17.5.0\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.5.0\" horizontal>\n Global `errors`, bug fixes with `zapier build` and auth field types.\n\n *Released: 2025-07-30*\n</Card>\n\n<Card title=\"What's changed in v17.4.0\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.4.0\" horizontal>\n Regression bug fixes with `zapier build`, support for compression of large input bundles.\n\n *Released: 2025-07-23*\n</Card>\n\n<Card title=\"What's changed in v17.3.1\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.3.1\" horizontal>\n Regression bug fixes with `zapier build`.\n\n *Released: 2025-07-17*\n</Card>\n\n<Card title=\"What's changed in v17.3.0\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.3.0\" horizontal>\n Revamped `zapier build` and input field grouping.\n\n *Released: 2025-07-01*\n</Card>\n\n<Card title=\"What's changed in v17.2.0\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.2.0\" horizontal>\n Improved large bundle handling.\n\n *Released: 2025-06-11*\n</Card>\n\n<Card title=\"What's changed in v17.1.0\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.1.0\" horizontal>\n Improved `zapier convert` and `zapier deprecate`.\n\n *Released: 2025-06-10*\n</Card>\n\n<Card title=\"What's changed in v17.0.4\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.0.4\" horizontal>\n Fixed a bug in `zapier build`.\n\n *Released: 2025-06-03*\n</Card>\n\n<Card title=\"What's changed in v17.0.3\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.0.3\" horizontal>\n Bug fixes on `zapier build`, `{{curlies}}` replacement, and more.\n\n *Released: 2025-05-30*\n</Card>\n\n<Card title=\"What's changed in v17.0.2\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.0.2\" horizontal>\n Windows and ESM bugs.\n\n *Released: 2025-05-19*\n</Card>\n\n<Card title=\"What's changed in v17.0.1\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.0.1\" horizontal>\n Fixed a regression bug on `zapier build` and the oauth2 template in `zapier init`.\n\n *Released: 2025-05-14*\n</Card>\n\n<Card title=\"What's changed in v17.0.0\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.0.0\" horizontal>\n ES module support, more complete typing, no more `{{curlies}}` in shorthand requests.\n\n *Released: 2025-05-12*\n</Card>\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2025/index", "source_repo": "", "source_path": "", "section": "news", "tags": ["2025", "changelog", "news"], "related": [], "meta": {"year": "2025"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2025/labeled-versions", "kind": "platform_news", "key": "2025/labeled-versions", "title": "Labeled Versions now available in CLI and Platform UI", "summary": "Labeled Versions now available in CLI and Platform UI", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# Labeled Versions now available in CLI and Platform UI\n\n> Integration version numbers can now include a label, to enable you to develop and test changes without committing to a [semantic version number](/integrations/manage/versions#version-numbering) until you're ready.\n\n*Released: 2025-10-21*\n\n## Labeled Versions\n\n* 🎉 [Labeled Versions](https://docs.zapier.com/integrations/manage/labeled-versions) are now publicly available!\n * Versions like `2.0.0-beta` can be used for testing and avoiding version collisions during parallel development\n * More flexible \"snapshot\" versions like `0.0.0-my-feature` can be used to push integration updates without committing to a semantic version number\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2025/labeled-versions", "source_repo": "", "source_path": "", "section": "news", "tags": ["2025", "changelog", "news"], "related": [], "meta": {"year": "2025"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2025/npm-package-sec-inc", "kind": "platform_news", "key": "2025/npm-package-sec-inc", "title": "Incident: Unauthorized Access to Zapier NPM Packages", "summary": "Incident: Unauthorized Access to Zapier NPM Packages", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# Incident: Unauthorized Access to Zapier NPM Packages\n\n> Please review the enclosed list of packages and recommendations for Zapier developers.\n\n*Released: 2025-11-24*\n\n## Unauthorized Access to Zapier npm Packages\n\n**Note: No action is needed from Zapier users**, only from Zapier developers using one of the NPM package versions listed [on this page](/integrations/build-cli/inc-547). See that link for detailed mitigation recommendations.\n\nAll Zapier products are operating as expected and there is no indication of data loss or leak.\n\nPlease [see this link](https://status.zapier.com/incidents/01KAV9DDHMYT7R6MFHSB8C09E3#updates) for the most up-to-date information.\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2025/npm-package-sec-inc", "source_repo": "", "source_path": "", "section": "news", "tags": ["2025", "changelog", "news"], "related": [], "meta": {"year": "2025"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2025/organization-user-migration-in-ui", "kind": "platform_news", "key": "2025/organization-user-migration-in-ui", "title": "Migration UI now supports individual and organization-level migrations", "summary": "Migration UI now supports individual and organization-level migrations", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# Migration UI now supports individual and organization-level migrations\n\n> Enhanced migration UI with granular control options for individual and organization-level migrations.\n\n*Released: 2025-10-02*\n\n## Migration via the Platform UI\n\n* 🎉 [Email-based migration](https://docs.zapier.com/integrations/manage/migrate#migrate-users-to-new-version-with-platform-ui) now supports two scopes:\n * **Individual**: Migrates only private Zap workflows under the user's individual account (equivalent to the `--user` flag of the `zapier migrate` CLI command)\n * **Organization**: Migrates all Zap workflows including shared resources across organization accounts (equivalent to the `--account` flag of the `zapier migrate` CLI command)\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2025/organization-user-migration-in-ui", "source_repo": "", "source_path": "", "section": "news", "tags": ["2025", "changelog", "news"], "related": [], "meta": {"year": "2025"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2025/static-ip-self-serve", "kind": "platform_news", "key": "2025/static-ip-self-serve", "title": "Self-serve static IP for private integrations", "summary": "Self-serve static IP for private integrations", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# Self-serve static IP for private integrations\n\n> Developers can now enable static IP addresses for private integrations directly in Platform UI without contacting support.\n\n*Released: 2025-10-21*\n\n## Self-serve static IP for private integrations\n\n* 🎉 [Static IP](https://docs.zapier.com/integrations/build/static-ip) can now be enabled by team members for private integrations:\n * **Platform UI toggle**: Navigate to the Settings tab on the Advanced page to enable static IP addresses for your private integration without contacting support.\n * **Published integrations**: Continue to contact Zapier Support to enable static IP for published integrations.\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2025/static-ip-self-serve", "source_repo": "", "source_path": "", "section": "news", "tags": ["2025", "changelog", "news"], "related": [], "meta": {"year": "2025"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2025/v17.0.0", "kind": "platform_news", "key": "2025/v17.0.0", "title": "What's changed in v17.0.0", "summary": "What's changed in v17.0.0", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v17.0.0\n\n> ES module support, more complete typing, no more `{{curlies}}` in shorthand requests.\n\n*Released: 2025-05-12*\n\nVersion 17.0.0 is a **BREAKING CHANGE** release that contains several important upgrades and changes. Here is a brief breakdown of the main breaking changes (**❗ denotes a breaking change**):\n\n## ES Module Support\n\nYou can now build integrations using modern ES Module syntax. This means you can use `import ... from ...` instead of `require(...)`, and use newer npm packages that support only ESM.\n\nTo start using ESM for your integration project:\n\n* Set `\"type\": \"module\"` in your `package.json`\n* Replace `main` with `exports` in your `package.json`\n\nFor a complete example, check out [minimal-esm](https://github.com/zapier/zapier-platform/tree/82b11aef29a4e7cb576431dba24cba0066c5057b/example-apps/minimal-esm) or [typescript-esm](https://github.com/zapier/zapier-platform/tree/82b11aef29a4e7cb576431dba24cba0066c5057b/example-apps/typescript-esm) (both can be initialized using [`zapier init`](https://github.com/zapier/zapier-platform/blob/82b11aef29a4e7cb576431dba24cba0066c5057b/packages/cli/docs/cli.md#init) with the `-m esm` flag).\n\nAdditionally, this update means it's no longer required for every integration's entry point to be `index.js` at the root directory. Instead, the entry point can be defined in `package.json`.\n\n* For example, see the Typescript ESM example integration [at this link](https://github.com/zapier/zapier-platform/tree/main/example-apps/typescript-esm) - it no longer contains an `index.js` file at the root directory, rather the entry point is defined via `\"exports\": \"./dist/index.js\"` in the integration's [package.json](https://github.com/zapier/zapier-platform/blob/main/example-apps/typescript-esm/package.json#L20)\n\n## Typing Improvements\n\nWe've improved the typing system, making the TypeScript dev experience more enjoyable. The new typing system includes:\n\n* Bundle `inputData` types is now inferred from input fields.\n* New helper functions to help with typing:\n * `defineApp`, `defineTrigger`, `defineCreate`, `defineSearch`, `defineInputFields`\n * These are now recommended over the equivalent `satisfies Xyz` statements\n * `satisfies` is still used for `perform` functions, with `InferInputData`, and for other features without `define` helpers. For example, `export default { ... } satisfies Authentication` is still expected.\n\nCheck out the [typescript-esm](https://github.com/zapier/zapier-platform/tree/82b11aef29a4e7cb576431dba24cba0066c5057b/example-apps/typescript-esm) example project for a full example.\n\n## ❗ No More `{{curly brackets}}` Outside of Shorthand Requests\n\nCalling `z.request()` with `{{bundle.*}}` or `{{process.env.*}}` will now result in an error. For example:\n\n```js theme={null}\nconst perform = async (z, bundle) => {\n const response = await z.request({\n url: \"https://{{bundle.authData.subdomain}}.example.com\",\n });\n return response.data;\n};\n```\n\nThis will result in an error in v17. Instead, you must use [template literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) i.e. `${var}`:\n\n```js theme={null}\nconst perform = async (z, bundle) => {\n const response = await z.request({\n url: `https://${bundle.authData.subdomain}.example.com`,\n });\n return response.data;\n};\n```\n\nHowever, `{{curly backets}}` are still (and have to be) allowed in other places, including `operation.lock.key`. They are also allowed (actually required) in usage of shorthand requests:\n\n```js theme={null}\n{\n operation: {\n perform: {\n url: 'https://{{bundle.authData.subdomain}}.example.com',\n method: 'GET',\n }\n }\n}\n```\n\n### ❗ Schema Changes\n\nWe have split authentication fields, input fields, and output fields into their own respective schemas, to allow for stricter schema checks and to prepare for future platform updates. Along with this, we have removed irrelevant or incompatible field types and properties from certain schemas.\n\nNote that a descriptive error will be thrown on `zapier validate` if your integration attempts to use an unsupported type or property to prompt you to change it; no need to manually check these. The updated schema are as follows:\n\n* `AuthenticationSchema.fields`:\n * The following **types** are no longer supported: `code`, `file`, `integer`, `text`\n * The following **properties** are no longer supported: `altersDynamicFields`, `dynamic`, `meta`, `primary`, `search`, `steadyState`\n* `BasicActionOperationSchema.inputFields`:\n * All **types** remain the same.\n * The following **properties** are no longer supported: `primary`, `steadyState`\n* `BasicActionOperationSchema.outputFields`:\n * The following **types** are no longer supported: `text`, `copy`, `code`\n * The following **properties** are no longer supported: `altersDynamicFields`, `choices`, `computed`, `dynamic`, `helpText`, `inputFormat`, `meta`, `placeholder`, `search`\n\n***\n\nApart from these major changes, here are the detailed release notes for this release (**note that ❗ denotes a breaking change**):\n\n## cli\n\n* 🎉 ESM support added to `zapier init` command via the `--module` flag - supports Minimal and Typescript templates ([#976](https://github.com/zapier/zapier-platform/pull/976))\n* 🔨 `zapier build` now uses `esbuild` instead of `browserify` to detect dependencies, for a faster experience building, and to better support ESM ([#946](https://github.com/zapier/zapier-platform/pull/946))\n* 🔨 Update `gulp-prettier` dependency from 4.0.0 to 5.0.0\n\n## core\n\n* ❗ Stop replacing `{{curlies}}` unless it's a shorthand request ([#1001](https://github.com/zapier/zapier-platform/pull/1001))\n* 🎉 ESM Support: Two versions of `zapierwrapper.js`, one CJS and one ESM, loaded dynamically depending on the app type ([#965](https://github.com/zapier/zapier-platform/pull/965))\n* 🐛 Not every `{{curlies}}` in the request object need to be recursively replaced ([#1001](https://github.com/zapier/zapier-platform/pull/1001))\n* 🐛 HTTP 500 along with status codes >500 are caught in RPC client ([#974](https://github.com/zapier/zapier-platform/pull/974))\n* 🔨 Remove Bluebird library, replace with native promises ([#980](https://github.com/zapier/zapier-platform/pull/980))\n* 🔨 Refactor middleware and lambda handler logic to use async/await instead of Promise chaining ([#980](https://github.com/zapier/zapier-platform/pull/980))\n* 🔨 Trim newline and whitespaces from request headers ([#1000](https://github.com/zapier/zapier-platform/pull/1000))\n\n## schema\n\n* ❗ Remove deprecated shouldLock property in the schema ([#988](https://github.com/zapier/zapier-platform/pull/988))\n* 🔨 FieldSchema has been split into separate schemas and renamed for clarity ([#957](https://github.com/zapier/zapier-platform/pull/957), [#998](https://github.com/zapier/zapier-platform/pull/998)). Changes include:\n * Input Fields (`PlainInputFieldSchema` and `InputFieldsSchema`)\n * Output Fields (`PlainOutputFieldSchema` and `OutputFieldsSchema`)\n * Authentication Fields (`AuthFieldSchema` and `AuthFieldsSchema`)\n* 🔨 A dedicated `BasicSearchOperationSchema` has been added ([#998](https://github.com/zapier/zapier-platform/pull/998))\n\n## misc\n\n* 🔨 Dependency updates - full list in the PR ([#1010](https://github.com/zapier/zapier-platform/pull/1010))\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2025/v17.0.0", "source_repo": "", "source_path": "", "section": "news", "tags": ["2025", "changelog", "news"], "related": [], "meta": {"year": "2025"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2025/v17.0.1", "kind": "platform_news", "key": "2025/v17.0.1", "title": "What's changed in v17.0.1", "summary": "What's changed in v17.0.1", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v17.0.1\n\n> Fixed a regression bug on `zapier build` and the oauth2 template in `zapier init`.\n\n*Released: 2025-05-14*\n\n## cli\n\n* 🐛 `zapier init` Typescript template OAuth2 implementation doesn't work out of the box ([#1022](https://github.com/zapier/zapier-platform/pull/1022))\n* 🐛 `version-store.js` is updated to show the Node and NPM versions for v17 ([#1020](https://github.com/zapier/zapier-platform/pull/1020))\n\n## core\n\n* 🐛 `zapier build` (and therefore also `zapier push`) hangs on the `Building app definition.json` step when it's run on an integration with a Core dependency of v17, and run via CLI with a version less than v17 ([#1020](https://github.com/zapier/zapier-platform/pull/1020))\n\n## schema\n\nNone!\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2025/v17.0.1", "source_repo": "", "source_path": "", "section": "news", "tags": ["2025", "changelog", "news"], "related": [], "meta": {"year": "2025"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2025/v17.0.2", "kind": "platform_news", "key": "2025/v17.0.2", "title": "What's changed in v17.0.2", "summary": "What's changed in v17.0.2", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v17.0.2\n\n> Windows and ESM bugs.\n\n*Released: 2025-05-19*\n\n## cli\n\n* 🐛 Fix crashing issues on Windows ([#1024](https://github.com/zapier/zapier-platform/pull/1024))\n* 💅 Default to ESM for `zapier init` if template supports it ([#1026](https://github.com/zapier/zapier-platform/pull/1026))\n\n## core\n\n* 🐛 ESM apps can't import `define` helpers from `zapier-platform-core` ([#1018](https://github.com/zapier/zapier-platform/pull/1018))\n\n## schema\n\nNone!\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2025/v17.0.2", "source_repo": "", "source_path": "", "section": "news", "tags": ["2025", "changelog", "news"], "related": [], "meta": {"year": "2025"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2025/v17.0.3", "kind": "platform_news", "key": "2025/v17.0.3", "title": "What's changed in v17.0.3", "summary": "What's changed in v17.0.3", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v17.0.3\n\n> Bug fixes on `zapier build`, `{{curlies}}` replacement, and more.\n\n*Released: 2025-05-30*\n\n## cli\n\n* 🐛 Fix \"Cannot find base config file\" tsconfig warning on `zapier build` ([#1033](https://github.com/zapier/zapier-platform/pull/1033))\n\n## core\n\n* 🐛 Fix various bugs with `{{curlies}}` replacement ([#1032](https://github.com/zapier/zapier-platform/pull/1032))\n* 🐛 Remove request body fields with undefined `{{curlies}}` when the content-type is `application/x-www-form-urlencoded` ([#1044](https://github.com/zapier/zapier-platform/pull/1044))\n* 🐛 `{{curlies}}` in `requestTemplate` aren't properly replaced ([#1034](https://github.com/zapier/zapier-platform/pull/1034))\n* 🐛 Fix unexpected line breaks in logged response content ([#1042](https://github.com/zapier/zapier-platform/pull/1042))\n\n## schema\n\nNone!\n\n## misc\n\n* 📜 Update example apps: [oauth2](https://github.com/zapier/zapier-platform/tree/8fcadb7d8eaa10d4eb99b84ec8df70a0bb9b8e16/example-apps/oauth2), [typescript](https://github.com/zapier/zapier-platform/tree/8fcadb7d8eaa10d4eb99b84ec8df70a0bb9b8e16/example-apps/typescript), [typescript-esm](https://github.com/zapier/zapier-platform/tree/8fcadb7d8eaa10d4eb99b84ec8df70a0bb9b8e16/example-apps/typescript-esm) ([#1036](https://github.com/zapier/zapier-platform/pull/1036))\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2025/v17.0.3", "source_repo": "", "source_path": "", "section": "news", "tags": ["2025", "changelog", "news"], "related": [], "meta": {"year": "2025"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2025/v17.0.4", "kind": "platform_news", "key": "2025/v17.0.4", "title": "What's changed in v17.0.4", "summary": "What's changed in v17.0.4", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v17.0.4\n\n> Fixed a bug in `zapier build`.\n\n*Released: 2025-06-03*\n\n## cli\n\n* 🐛 Fix \"Cannot find module...\" error after running `zapier build` on a CJS integration using hybrid packages([#1046](https://github.com/zapier/zapier-platform/pull/1046))\n\n## core\n\nNone!\n\n## schema\n\nNone!\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2025/v17.0.4", "source_repo": "", "source_path": "", "section": "news", "tags": ["2025", "changelog", "news"], "related": [], "meta": {"year": "2025"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2025/v17.1.0", "kind": "platform_news", "key": "2025/v17.1.0", "title": "What's changed in v17.1.0", "summary": "What's changed in v17.1.0", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v17.1.0\n\n> Improved `zapier convert` and `zapier deprecate`.\n\n*Released: 2025-06-10*\n\n## cli\n\n* 🎉 `zapier convert` now accepts an app definition via the `--json` flag ([#1048](https://github.com/zapier/zapier-platform/pull/1048))\n* 💅 `zapier deprecate` now prompts for deprecation reason ([#1045](https://github.com/zapier/zapier-platform/pull/1045))\n\n## core\n\nNone!\n\n## schema\n\nNone!\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2025/v17.1.0", "source_repo": "", "source_path": "", "section": "news", "tags": ["2025", "changelog", "news"], "related": [], "meta": {"year": "2025"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2025/v17.2.0", "kind": "platform_news", "key": "2025/v17.2.0", "title": "What's changed in v17.2.0", "summary": "What's changed in v17.2.0", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v17.2.0\n\n> Improved large bundle handling.\n\n*Released: 2025-06-11*\n\n## cli\n\nNone!\n\n## core\n\n* 🎉 Add before middleware to fetch stashed bundles for improved large payload handling ([#1050](https://github.com/zapier/zapier-platform/pull/1050))\n\n## schema\n\nNone!\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2025/v17.2.0", "source_repo": "", "source_path": "", "section": "news", "tags": ["2025", "changelog", "news"], "related": [], "meta": {"year": "2025"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2025/v17.3.0", "kind": "platform_news", "key": "2025/v17.3.0", "title": "What's changed in v17.3.0", "summary": "What's changed in v17.3.0", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v17.3.0\n\n> Revamped `zapier build` and input field grouping.\n\n*Released: 2025-07-01*\n\nThis release introduces two major improvements: `zapier build` and input field grouping.\n\nThe `zapier build` command has been revamped to:\n\n* Better support npm/yarn/pnpm workspaces\n* Run faster when the `--skip-npm-install` flag is enabled\n* Test the build.zip file to verify all load-time dependencies are included (not applicable on Windows)\n\nInput Field Grouping:\n\n* Grouping support, intended for visual purpose in products, has been added to the input fields.\n\n## cli\n\n* 💅 `zapier build` supports npm/yarn/pnpm workspaces and runs faster ([#1052](https://github.com/zapier/zapier-platform/pull/1052))\n* 🐛 Fix a bug where `zapier build` can select the wrong entry point of a dependency ([#1052](https://github.com/zapier/zapier-platform/pull/1052) - [c004298](https://github.com/zapier/zapier-platform/pull/1052/commits/c004298a1b61b7de777f3c8222949c7d38d8826f))\n* 📜 Update docs for new days before deprecation and sending emails ([#1056](https://github.com/zapier/zapier-platform/pull/1056))\n\n## core\n\n* 🐛 Fix a bug where Fetch logger crashes when response doesn't have content-type ([#1062](https://github.com/zapier/zapier-platform/pull/1062))\n* 🐛 Fix a bug where `text/xml` response content should be logged ([#1058](https://github.com/zapier/zapier-platform/pull/1058))\n* 💅 Typing update: allow overriding `id` requirement in polling triggers ([#1059](https://github.com/zapier/zapier-platform/pull/1059))\n* 💅 Typing update: allow test bundles to be recursively partial ([#1057](https://github.com/zapier/zapier-platform/pull/1057))\n* 🔨 Bump fernet from 0.4.0 to 0.3.3 (latest) ([#1055](https://github.com/zapier/zapier-platform/pull/1055))\n\n## schema\n\n* 🎉 Input fields now support visual grouping through the \"group\" property of the `/PlainInputFieldSchema` and the new `/InputFieldGroupsSchema` ([#1061](https://github.com/zapier/zapier-platform/pull/1061))\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2025/v17.3.0", "source_repo": "", "source_path": "", "section": "news", "tags": ["2025", "changelog", "news"], "related": [], "meta": {"year": "2025"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2025/v17.3.1", "kind": "platform_news", "key": "2025/v17.3.1", "title": "What's changed in v17.3.1", "summary": "What's changed in v17.3.1", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v17.3.1\n\n> Regression bug fixes with `zapier build`.\n\n*Released: 2025-07-17*\n\n## cli\n\n* 🐛 Fix regression bugs with `zapier build --skip-npm-install`, where:\n * it can miss local packages files when building in a Lerna monorepo ([#1068](https://github.com/zapier/zapier-platform/pull/1068))\n * it can fail with \"Configuration property ... is not defined\" when [config](https://www.npmjs.com/package/config) package is used ([#1071](https://github.com/zapier/zapier-platform/pull/1071))\n* 💅 Improve some error messages in `zapier build` ([#1070](https://github.com/zapier/zapier-platform/pull/1070))\n\n## core\n\n* 💅 Improve the error message when the app module fails to import ([#1070](https://github.com/zapier/zapier-platform/pull/1070))\n\n## schema\n\nNone!\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2025/v17.3.1", "source_repo": "", "source_path": "", "section": "news", "tags": ["2025", "changelog", "news"], "related": [], "meta": {"year": "2025"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2025/v17.4.0", "kind": "platform_news", "key": "2025/v17.4.0", "title": "What's changed in v17.4.0", "summary": "What's changed in v17.4.0", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v17.4.0\n\n> Regression bug fixes with `zapier build`, support for compression of large input bundles.\n\n*Released: 2025-07-23*\n\n## cli\n\n* 🐛 Fix regression bugs with `zapier build`, where it can fail with \"'The \"path\" argument must be of type string'\" when [dirent.parentPath](https://nodejs.org/docs/latest/api/fs.html#direntparentpath) property is missing ([#1087](https://github.com/zapier/zapier-platform/pull/1087))\n* 🐛 Fixes a regression where `zapier build --skip-npm-install` fails when an app has a linked dependencies in its `node_modules` ([#1089](https://github.com/zapier/zapier-platform/pull/1089))\n* 🐛 Remove empty array at the end of `zapier versions -f json` ([#1086](https://github.com/zapier/zapier-platform/pull/1086))\n* 💅 Add additional Typescript auth options to `zapier init` ([#1067](https://github.com/zapier/zapier-platform/pull/1067))\n\n## core\n\n* 💅 Support compression when stashing large input bundles ([#1085](https://github.com/zapier/zapier-platform/pull/1085))\n\n## schema\n\nNone!\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2025/v17.4.0", "source_repo": "", "source_path": "", "section": "news", "tags": ["2025", "changelog", "news"], "related": [], "meta": {"year": "2025"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2025/v17.5.0", "kind": "platform_news", "key": "2025/v17.5.0", "title": "What's changed in v17.5.0", "summary": "What's changed in v17.5.0", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v17.5.0\n\n> Global `errors`, bug fixes with `zapier build` and auth field types.\n\n*Released: 2025-07-30*\n\n## cli\n\n* 🐛 Fix missing `bundle.inputDataRaw` in invoke command ([#1072](https://github.com/zapier/zapier-platform/pull/1072))\n* 🐛 Fix error `'No loader is configured for \".node\" files'` on `zapier build` ([#1094](https://github.com/zapier/zapier-platform/pull/1094))\n* 🔨 Refactor `zapier init` to move auth befores/afters into `middleware.js` instead of `authentication.js` ([#1073](https://github.com/zapier/zapier-platform/pull/1073))\n\n## core\n\n* 💅 Export errors from `zapier-platform-core` ([#1075](https://github.com/zapier/zapier-platform/pull/1075))\n* 🔨 Update `form-data` from `4.0.1` to `4.0.4` ([#1096](https://github.com/zapier/zapier-platform/pull/1096))\n\n## schema\n\n* 💅 Expanded `AuthFieldSchema` with additional field types:\n * Added support for the `integer` type ([#1095](https://github.com/zapier/zapier-platform/pull/1095)).\n * Added support for the `text` type ([#1098](https://github.com/zapier/zapier-platform/pull/1098)).\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2025/v17.5.0", "source_repo": "", "source_path": "", "section": "news", "tags": ["2025", "changelog", "news"], "related": [], "meta": {"year": "2025"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2025/v17.6.0", "kind": "platform_news", "key": "2025/v17.6.0", "title": "What's changed in v17.6.0", "summary": "What's changed in v17.6.0", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v17.6.0\n\n> Global `console` object and account filtering for `zapier canary`.\n\n*Released: 2025-08-11*\n\n## cli\n\n* 💅 Add user and account filters to canary ([#1066](https://github.com/zapier/zapier-platform/pull/1066))\n\n## core\n\n* 💅 Export `console` from zapier-platform-core ([#1077](https://github.com/zapier/zapier-platform/pull/1077), [#1102](https://github.com/zapier/zapier-platform/pull/1102))\n* 🐛 Allow safe `authData` keys to be logged uncensored ([#1097](https://github.com/zapier/zapier-platform/pull/1097))\n\n## schema\n\nNone!\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2025/v17.6.0", "source_repo": "", "source_path": "", "section": "news", "tags": ["2025", "changelog", "news"], "related": [], "meta": {"year": "2025"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2025/v17.7.0", "kind": "platform_news", "key": "2025/v17.7.0", "title": "What's changed in v17.7.0", "summary": "What's changed in v17.7.0", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v17.7.0\n\n> This update lays groundwork for Search Pagination, which will allow Search steps to paginate through results so that the most relevant results can be returned. However, this is not yet supported by any Zapier products.\n\n*Released: 2025-08-22*\n\n## cli\n\n* 🐛 Fix `zapier pull` error \"listFiles is not a function\" ([#1113](https://github.com/zapier/zapier-platform/pull/1113))\n* 🐛 Fix `zapier invoke auth` writing object values to `.env` as `[object Object]` ([#1107](https://github.com/zapier/zapier-platform/pull/1107))\n* 💅 Add logic to `zapier build` to handle the case where the app directory has symlinks to files on a different drive ([#1106](https://github.com/zapier/zapier-platform/pull/1106))\n* 🎉 `zapier invoke` supports testing Search Pagination with a `paging_token` flag ([#1082](https://github.com/zapier/zapier-platform/pull/1082))\n\n## core\n\n* 🎉 Foundational support for Search Pagination ([#1082](https://github.com/zapier/zapier-platform/pull/1082))\n\n## schema\n\n* 🎉 Schema support for Search Pagination ([#1082](https://github.com/zapier/zapier-platform/pull/1082))\n\n## misc\n\n* 💅 Enable Windows in Github Actions CI ([#1106](https://github.com/zapier/zapier-platform/pull/1106))\n* 💅 Add Claude, Copilot, and Cursor instructions/rules ([#1107](https://github.com/zapier/zapier-platform/pull/1107))\n* 🔨 Bump `tmp` from 0.2.3 to 0.2.4 ([#1100](https://github.com/zapier/zapier-platform/pull/1100))\n* 🔨 Bump `sha.js` from 2.4.11 to 2.4.12 ([#1116](https://github.com/zapier/zapier-platform/pull/1116))\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2025/v17.7.0", "source_repo": "", "source_path": "", "section": "news", "tags": ["2025", "changelog", "news"], "related": [], "meta": {"year": "2025"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2025/v17.7.1", "kind": "platform_news", "key": "2025/v17.7.1", "title": "What's changed in v17.7.1", "summary": "What's changed in v17.7.1", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v17.7.1\n\n> Improved `zapier scaffold`, `zapier init`, `zapier validate`, and `zapier invoke auth`. Also fixed issues with uncensored sensitive information and field grouping schema.\n\n*Released: 2025-09-10*\n\n## cli\n\n* 🐛 Fix `zapier scaffold` failing when app object contains spread elements ([#1115](https://github.com/zapier/zapier-platform/pull/1115))\n* 🐛 Fix `zapier invoke auth` may append to last line without a newline ([#1138](https://github.com/zapier/zapier-platform/pull/1138))\n* 🐛 Fix `zapier scaffold` to use `.js` extension for TS imports ([#1123](https://github.com/zapier/zapier-platform/pull/1123))\n* 🐛 Fix `zapier scaffold` to handle shorthand property syntax ([#1125](https://github.com/zapier/zapier-platform/pull/1125))\n* 💅 `zapier validate` now runs `_zapier-build` before validation by default ([#1130](https://github.com/zapier/zapier-platform/pull/1130))\n* 💅 Add `dev` script to `package.json` of typescript templates generated by `zapier init` ([#1128](https://github.com/zapier/zapier-platform/pull/1128))\n* 💅 Improve `zapier init` to list only templates that support selected module and language ([#1146](https://github.com/zapier/zapier-platform/pull/1146))\n\n## core\n\n* 🐛 Censor sensitive info in `ResponseError` ([#1147](https://github.com/zapier/zapier-platform/pull/1147))\n\n## schema\n\n* 🐛 Fix `InputFieldGroupsSchema` to have its properties displayed ([#1143](https://github.com/zapier/zapier-platform/pull/1143))\n* 🧪 Allow to skip cleaning arrays in `inputData` via `skipCleanArrayInputData` ([#1153](https://github.com/zapier/zapier-platform/pull/1153))\n* 🔨 Support version with label (ongoing work) ([#1093](https://github.com/zapier/zapier-platform/pull/1093))\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2025/v17.7.1", "source_repo": "", "source_path": "", "section": "news", "tags": ["2025", "changelog", "news"], "related": [], "meta": {"year": "2025"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2025/v17.7.2", "kind": "platform_news", "key": "2025/v17.7.2", "title": "What's changed in v17.7.2", "summary": "What's changed in v17.7.2", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v17.7.2\n\n> Fixed issues with typing and semver restriction.\n\n*Released: 2025-09-17*\n\n## cli\n\n* 🐛 Allows deleting old non-semver versions and blocks pushes to non-semver versions ([#1160](https://github.com/zapier/zapier-platform/pull/1160))\n* 🐛 Integration check displays failure icon if errors are present ([#1159](https://github.com/zapier/zapier-platform/pull/1159))\n\n## core\n\n* 🐛 Adds paging\\_token to bundle.meta types ([#1157](https://github.com/zapier/zapier-platform/pull/1157))\n\n## misc\n\n* 🔨 Bump vite from 6.3.5 to 6.3.6 ([#1156](https://github.com/zapier/zapier-platform/pull/1156))\n* 🔨 Improve types ([#1162](https://github.com/zapier/zapier-platform/pull/1162), [#1164](https://github.com/zapier/zapier-platform/pull/1164), [#1165](https://github.com/zapier/zapier-platform/pull/1165))\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2025/v17.7.2", "source_repo": "", "source_path": "", "section": "news", "tags": ["2025", "changelog", "news"], "related": [], "meta": {"year": "2025"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2025/v17.8.0", "kind": "platform_news", "key": "2025/v17.8.0", "title": "What's changed in v17.8.0", "summary": "What's changed in v17.8.0", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v17.8.0\n\n> Added flexibility for Search Pagination and cleaning up some dependencies. Zapier push now supports snapshot publishing.\n\n*Released: 2025-10-07*\n\nAside from some clean up work, this release adds support for natural snapshots to `zapier push`. This is currently only supported internally but look out for a public release soon!\n\n## cli\n\n* 💅 `zapier push` supports natural snapshots ([#1172](https://github.com/zapier/zapier-platform/pull/1172))\n* 🐛 Address `punycode` deprecation warning by removing `node-fetch` ([#1171](https://github.com/zapier/zapier-platform/pull/1171))\n* 📜 Fix incorrect docs in `zapier migrate` ([#1169](https://github.com/zapier/zapier-platform/pull/1169))\n\n## core\n\n* 🐛 Allow null and undefined values for `page_token` in `SearchResult` ([#1168](https://github.com/zapier/zapier-platform/pull/1168))\n* 🐛 Allow undefined value for `paging_token` ([#1166](https://github.com/zapier/zapier-platform/pull/1166))\n\n## misc\n\n* 📜 Direct developers to Platform News ([#1174](https://github.com/zapier/zapier-platform/pull/1174))\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2025/v17.8.0", "source_repo": "", "source_path": "", "section": "news", "tags": ["2025", "changelog", "news"], "related": [], "meta": {"year": "2025"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2025/v17.9.0", "kind": "platform_news", "key": "2025/v17.9.0", "title": "What's changed in v17.9.0", "summary": "What's changed in v17.9.0", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v17.9.0\n\n> Bugfix for snapshot flag, improvements for `zapier env`.\n\n*Released: 2025-10-20*\n\nThis release fixes an issue with validation for labeled versions, and improves failures on `zapier env:set`.\n\n## cli\n\n* 🐛 Validate snapshot labels for 12 chars instead of 18 ([#1182](https://github.com/zapier/zapier-platform/pull/1182))\n* 💅 Display failure reasons for env:set ([#1180](https://github.com/zapier/zapier-platform/pull/1180))\n\n## core\n\nNone!\n\n## schema\n\nNone!\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2025/v17.9.0", "source_repo": "", "source_path": "", "section": "news", "tags": ["2025", "changelog", "news"], "related": [], "meta": {"year": "2025"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2025/v17.9.1", "kind": "platform_news", "key": "2025/v17.9.1", "title": "What's changed in v17.9.1", "summary": "What's changed in v17.9.1", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v17.9.1\n\n> Bug fix for zapier push and dependency updates.\n\n*Released: 2025-10-28*\n\nThis release addresses a bug in the `zapier push` command and includes dependency updates.\n\n## cli\n\n* 🐛 Fix issue where zapier push fail if the app wasn't built already (may have affected ESM builds) ([#1187](https://github.com/zapier/zapier-platform/pull/1187))\n\n## core\n\nNone!\n\n## schema\n\nNone!\n\n## misc\n\n* 🔨 Bump vite from 6.3.6 to 6.4.1 ([#1185](https://github.com/zapier/zapier-platform/pull/1185))\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2025/v17.9.1", "source_repo": "", "source_path": "", "section": "news", "tags": ["2025", "changelog", "news"], "related": [], "meta": {"year": "2025"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2025/v18.0.0", "kind": "platform_news", "key": "2025/v18.0.0", "title": "What's changed in v18.0.0", "summary": "What's changed in v18.0.0", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v18.0.0\n\n> Node.js 22 support, new throttling middleware, and a new CLI executable name `zapier-platform`.\n\n*Released: 2025-10-30*\n\nVersion 18.0.0 is a **BREAKING CHANGE** release that contains several important upgrades and changes. Here is a brief breakdown of the main changes (**❗ denotes a breaking change**):\n\n## ❗ Node.js 22 Support\n\nZapier Platform v18 runs on Node.js 22 runtime. This is a breaking change as it may affect compatibility with older Node.js versions and dependencies.\n\n## ❗ Schema Changes\n\nThe `skipCleanArrayInputData` experimental flag has been replaced with `cleanInputData`. This provides more consistent data cleaning behavior across the platform. This change is breaking **only if** you're using `skipCleanArrayInputData`.\nSee [cleanInputData flag documentation](/integrations/build-cli/empty-values-in-input-data) for more details on how to configure this behavior.\n\n## ❗ New Throttling Middleware\n\nA new `throwForThrottling` middleware has been added to prevent `afterResponse` middleware from suppressing 429 (throttling) responses. This ensures proper handling of rate limiting scenarios. This change is breaking **if** you want to handle 429 responses in your `afterResponse`. See [v18.x and above: the built-in `throwForThrottling` middleware](/integrations/build-cli/making-http-requests#v18-x-and-above%3A-the-built-in-throwforthrottling-middleware) for how to handle 429s yourself.\n\n## New Executable Name `zapier-platform`\n\nThe CLI now includes a new executable name `zapier-platform` while deprecating the old `zapier` command. Both will work for now, but `zapier-platform` is the recommended command going forward.\n\n***\n\nApart from these major changes, here are the detailed release notes for this release (**note that ❗ denotes a breaking change**):\n\n## cli\n\n* 🎉 Add executable name `zapier-platform` and deprecate `zapier` ([#1181](https://github.com/zapier/zapier-platform/pull/1181))\n* 🔨 Update outdated dependencies with security vulnerabilities ([#1111](https://github.com/zapier/zapier-platform/pull/1111))\n* 🔨 Apply prettier formatting to generated auth files since gen.fs.write bypasses transform streams\n* 🔨 Add ESM wrapper improvements for better module support\n\n## core\n\n* ❗ Add Node.js 22 support ([#1078](https://github.com/zapier/zapier-platform/pull/1078))\n* 🎉 Add `throwForThrottling` middleware with backward-compatible default behavior ([#1151](https://github.com/zapier/zapier-platform/pull/1151))\n* 🐛 Add better error message for 413 responses ([#1110](https://github.com/zapier/zapier-platform/pull/1110))\n\n## schema\n\n* ❗ Replace `skipCleanArrayInputData` with `cleanInputData` ([#1183](https://github.com/zapier/zapier-platform/pull/1183))\n* 🔨 Add global `cleanInputData` flag for consistent data cleaning behavior\n\n## misc\n\n* ❗ Major dependency updates across all packages ([#1079](https://github.com/zapier/zapier-platform/pull/1079))\n* 🔨 Update CI configuration for Node.js 22 support\n* 🔨 Pin exact xmldom version for security\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2025/v18.0.0", "source_repo": "", "source_path": "", "section": "news", "tags": ["2025", "changelog", "news"], "related": [], "meta": {"year": "2025"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2025/v18.0.1", "kind": "platform_news", "key": "2025/v18.0.1", "title": "What's changed in v18.0.1", "summary": "What's changed in v18.0.1", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v18.0.1\n\n> Bug fixes for npx resolution and TypeScript typing for line items.\n\n*Released: 2025-11-05*\n\nThis release addresses an npx resolution issue introduced in v18.0.0 and fixes TypeScript typing for nested input fields when working with line items.\n\n## cli\n\n* 🐛 Fix npx resolution issue with dual binary entries ([#1191](https://github.com/zapier/zapier-platform/pull/1191))\n\n## core\n\n* 🐛 Fix children input types when line items are present ([#1188](https://github.com/zapier/zapier-platform/pull/1188))\n\n## schema\n\nNone!\n\n## misc\n\nNone!\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2025/v18.0.1", "source_repo": "", "source_path": "", "section": "news", "tags": ["2025", "changelog", "news"], "related": [], "meta": {"year": "2025"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2025/v18.0.5", "kind": "platform_news", "key": "2025/v18.0.5", "title": "What's changed in v18.0.5", "summary": "What's changed in v18.0.5", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v18.0.5\n\n> A security fix on the CLI.\n\n*Released: 2025-12-10*\n\n<Info>\n We're releasing v18.0.5, skipping comprimised versions v18.0.2, v18.0.3, and\n v18.0.4, due to the prior [security\n incident](/integrations/news/2025/npm-package-sec-inc).\n</Info>\n\nThis release fixes a potential security vulnerability in the `build` command related to zip file decompression.\n\n## cli\n\n* 🐛 Remove problematic decompress-tar dependency ([#1202](https://github.com/zapier/zapier-platform/pull/1202))\n\n## core\n\nNone!\n\n## schema\n\nNone!\n\n## misc\n\n* 🔨 Switch to pnpm as package manager and task runner ([#1204](https://github.com/zapier/zapier-platform/pull/1204))\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2025/v18.0.5", "source_repo": "", "source_path": "", "section": "news", "tags": ["2025", "changelog", "news"], "related": [], "meta": {"year": "2025"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2025/v18.0.6", "kind": "platform_news", "key": "2025/v18.0.6", "title": "What's changed in v18.0.6", "summary": "What's changed in v18.0.6", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v18.0.6\n\n> Package manager detection from `zapier build`\n\n*Released: 2025-12-24*\n\nThe `zapier build` command was harcoded to use `npm install`. As alternate package managers gain adoption, the `zapier build` command will respect your app's package manager of choice.\nIt does this by checking the `packageManager` on the package.json file. If it is not defined, it will look for any relevant lock files. If still, none is defined, then will fallback to `npm`.\n\nIf you are familiar with using `zapier build` with the flag `--skip-npm-install`, this flag has been renamed to `--skip-dep-install`, but will continue to still work as an alias. In the future, we will remove the `--skip-npm-install` flag.\n\n## cli\n\n* 💅 CLI build respects the integration's package manager ([#1216](https://github.com/zapier/zapier-platform/pull/1216))\n\n## core\n\nNone!\n\n## schema\n\nNone!\n\n## misc\n\n* 🔨 Bump tmp from 0.2.4 to 0.2.5 ([#1207](https://github.com/zapier/zapier-platform/pull/1207))\n* 🔨 Bump form-data from 4.0.4 to 4.0.5 ([#1208](https://github.com/zapier/zapier-platform/pull/1208))\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2025/v18.0.6", "source_repo": "", "source_path": "", "section": "news", "tags": ["2025", "changelog", "news"], "related": [], "meta": {"year": "2025"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2025", "kind": "platform_news", "key": "2025", "title": "Platform News in 2025", "summary": "Platform News in 2025", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# Platform News in 2025\n\n<Card title=\"What's changed in v18.0.6\" icon=\"newspaper\" href=\"/integrations/news/2025/v18.0.6\" horizontal>\n Package manager detection from `zapier build`\n\n *Released: 2025-12-24*\n</Card>\n\n<Card title=\"What's changed in v18.0.5\" icon=\"newspaper\" href=\"/integrations/news/2025/v18.0.5\" horizontal>\n A security fix on the CLI.\n\n *Released: 2025-12-10*\n</Card>\n\n<Card title=\"Incident: Unauthorized Access to Zapier NPM Packages\" icon=\"newspaper\" href=\"/integrations/news/2025/npm-package-sec-inc\" horizontal>\n Please review the enclosed list of packages and recommendations for Zapier developers.\n\n *Released: 2025-11-24*\n</Card>\n\n<Card title=\"What's changed in v18.0.1\" icon=\"newspaper\" href=\"/integrations/news/2025/v18.0.1\" horizontal>\n Bug fixes for npx resolution and TypeScript typing for line items.\n\n *Released: 2025-11-05*\n</Card>\n\n<Card title=\"What's changed in v18.0.0\" icon=\"newspaper\" href=\"/integrations/news/2025/v18.0.0\" horizontal>\n Node.js 22 support, new throttling middleware, and a new CLI executable name `zapier-platform`.\n\n *Released: 2025-10-30*\n</Card>\n\n<Card title=\"What's changed in v17.9.1\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.9.1\" horizontal>\n Bug fix for zapier push and dependency updates.\n\n *Released: 2025-10-28*\n</Card>\n\n<Card title=\"Self-serve static IP for private integrations\" icon=\"newspaper\" href=\"/integrations/news/2025/static-ip-self-serve\" horizontal>\n Developers can now enable static IP addresses for private integrations directly in Platform UI without contacting support.\n\n *Released: 2025-10-21*\n</Card>\n\n<Card title=\"Labeled Versions now available in CLI and Platform UI\" icon=\"newspaper\" href=\"/integrations/news/2025/labeled-versions\" horizontal>\n Integration version numbers can now include a label, to enable you to develop and test changes without committing to a [semantic version number](/integrations/manage/versions#version-numbering) until you're ready.\n\n *Released: 2025-10-21*\n</Card>\n\n<Card title=\"What's changed in v17.9.0\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.9.0\" horizontal>\n Bugfix for snapshot flag, improvements for `zapier env`.\n\n *Released: 2025-10-20*\n</Card>\n\n<Card title=\"What's changed in v17.8.0\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.8.0\" horizontal>\n Added flexibility for Search Pagination and cleaning up some dependencies. Zapier push now supports snapshot publishing.\n\n *Released: 2025-10-07*\n</Card>\n\n<Card title=\"Migration UI now supports individual and organization-level migrations\" icon=\"newspaper\" href=\"/integrations/news/2025/organization-user-migration-in-ui\" horizontal>\n Enhanced migration UI with granular control options for individual and organization-level migrations.\n\n *Released: 2025-10-02*\n</Card>\n\n<Card title=\"What's changed in v17.7.2\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.7.2\" horizontal>\n Fixed issues with typing and semver restriction.\n\n *Released: 2025-09-17*\n</Card>\n\n<Card title=\"What's changed in v17.7.1\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.7.1\" horizontal>\n Improved `zapier scaffold`, `zapier init`, `zapier validate`, and `zapier invoke auth`. Also fixed issues with uncensored sensitive information and field grouping schema.\n\n *Released: 2025-09-10*\n</Card>\n\n<Card title=\"No more manual handling of 4xx errors in refreshAccessToken\" icon=\"lightbulb-on\" href=\"/integrations/news/2025/4xx-errors-refreshAccessToken\" horizontal>\n We now automatically handle 4xx error responses when refreshing OAuth2 access tokens.\n\n *Effective: 2025-09-08*\n</Card>\n\n<Card title=\"What's changed in v17.7.0\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.7.0\" horizontal>\n This update lays groundwork for Search Pagination, which will allow Search steps to paginate through results so that the most relevant results can be returned. However, this is not yet supported by any Zapier products.\n\n *Released: 2025-08-22*\n</Card>\n\n<Card title=\"What's changed in v17.6.0\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.6.0\" horizontal>\n Global `console` object and account filtering for `zapier canary`.\n\n *Released: 2025-08-11*\n</Card>\n\n<Card title=\"What's changed in v17.5.0\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.5.0\" horizontal>\n Global `errors`, bug fixes with `zapier build` and auth field types.\n\n *Released: 2025-07-30*\n</Card>\n\n<Card title=\"What's changed in v17.4.0\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.4.0\" horizontal>\n Regression bug fixes with `zapier build`, support for compression of large input bundles.\n\n *Released: 2025-07-23*\n</Card>\n\n<Card title=\"What's changed in v17.3.1\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.3.1\" horizontal>\n Regression bug fixes with `zapier build`.\n\n *Released: 2025-07-17*\n</Card>\n\n<Card title=\"What's changed in v17.3.0\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.3.0\" horizontal>\n Revamped `zapier build` and input field grouping.\n\n *Released: 2025-07-01*\n</Card>\n\n<Card title=\"What's changed in v17.2.0\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.2.0\" horizontal>\n Improved large bundle handling.\n\n *Released: 2025-06-11*\n</Card>\n\n<Card title=\"What's changed in v17.1.0\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.1.0\" horizontal>\n Improved `zapier convert` and `zapier deprecate`.\n\n *Released: 2025-06-10*\n</Card>\n\n<Card title=\"What's changed in v17.0.4\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.0.4\" horizontal>\n Fixed a bug in `zapier build`.\n\n *Released: 2025-06-03*\n</Card>\n\n<Card title=\"What's changed in v17.0.3\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.0.3\" horizontal>\n Bug fixes on `zapier build`, `{{curlies}}` replacement, and more.\n\n *Released: 2025-05-30*\n</Card>\n\n<Card title=\"What's changed in v17.0.2\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.0.2\" horizontal>\n Windows and ESM bugs.\n\n *Released: 2025-05-19*\n</Card>\n\n<Card title=\"What's changed in v17.0.1\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.0.1\" horizontal>\n Fixed a regression bug on `zapier build` and the oauth2 template in `zapier init`.\n\n *Released: 2025-05-14*\n</Card>\n\n<Card title=\"What's changed in v17.0.0\" icon=\"newspaper\" href=\"/integrations/news/2025/v17.0.0\" horizontal>\n ES module support, more complete typing, no more `{{curlies}}` in shorthand requests.\n\n *Released: 2025-05-12*\n</Card>\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2025", "source_repo": "", "source_path": "", "section": "news", "tags": ["changelog", "news"], "related": [], "meta": {"year": "2025.md"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2026/index", "kind": "platform_news", "key": "2026/index", "title": "Platform News in 2026", "summary": "Platform News in 2026", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# Platform News in 2026\n\n<Card title=\"What's changed in v19.1.0\" icon=\"newspaper\" href=\"/integrations/news/2026/v19.1.0\" horizontal>\n Auth template rendering can honor the real outbound request and custom request properties, plus a fix for the `appTester` type signature\n\n *Released: 2026-07-30*\n</Card>\n\n<Card title=\"What's changed in v19.0.0\" icon=\"newspaper\" href=\"/integrations/news/2026/v19.0.0\" horizontal>\n The `zapier` CLI binary has been removed. Use `zapier-platform` instead.\n\n *Released: 2026-05-18*\n</Card>\n\n<Card title=\"New platform guardrails for safer integration versioning\" icon=\"newspaper\" href=\"/integrations/news/2026/version-promotion-guardrails\" horizontal>\n The platform now checks for breaking changes during promotion and guides you toward the correct semantic version, helping protect your users from unexpected disruptions.\n\n *Effective: 2026-05-12*\n</Card>\n\n<Card title=\"What's changed in v18.6.0\" icon=\"newspaper\" href=\"/integrations/news/2026/v18.6.0\" horizontal>\n New `invoke auth template` and `invoke auth render` commands for inspecting an app's auth request shape\n\n *Released: 2026-05-05*\n</Card>\n\n<Card title=\"What's changed in v18.5.1\" icon=\"newspaper\" href=\"/integrations/news/2026/v18.5.1\" horizontal>\n Actionable error when app definition fails to load, `platformData` removed from bundle, docs and `help` updated to use `zapier-platform` binary name\n\n *Released: 2026-04-30*\n</Card>\n\n<Card title=\"What's changed in v18.5.0\" icon=\"newspaper\" href=\"/integrations/news/2026/v18.5.0\" horizontal>\n Line item support in `invoke`, falsy value fixes, new `line-items` project template\n\n *Released: 2026-04-16*\n</Card>\n\n<Card title=\"What's changed in v18.4.0\" icon=\"newspaper\" href=\"/integrations/news/2026/v18.4.0\" horizontal>\n JSON input field type, `versions` command improvements, function-based dynamic dropdown fix\n\n *Released: 2026-04-06*\n</Card>\n\n<Card title=\"What's changed in v18.3.0\" icon=\"newspaper\" href=\"/integrations/news/2026/v18.3.0\" horizontal>\n Bug fixes and improvements\n\n *Released: 2026-03-12*\n</Card>\n\n<Card title=\"What's changed in v18.2.3\" icon=\"newspaper\" href=\"/integrations/news/2026/v18.2.3\" horizontal>\n Bug fixes and improvements\n\n *Released: 2026-03-04*\n</Card>\n\n<Card title=\"What's changed in v18.2.2\" icon=\"newspaper\" href=\"/integrations/news/2026/v18.2.2\" horizontal>\n Bug fix for legacy-scripting-runner module loading\n\n *Released: 2026-02-26*\n</Card>\n\n<Card title=\"User migrations must stay within the same major version\" icon=\"newspaper\" href=\"/integrations/news/2026/migrations-same-major-version\" horizontal>\n The Platform UI and CLI now block migrating users when the source and target integration versions differ in their [semantic major version](/integrations/manage/versions#version-numbering)—for example, you cannot migrate from `1.x.x` to `2.x.x`.\n\n *Effective: 2026-02-26*\n</Card>\n\n<Card title=\"What's changed in v18.2.1\" icon=\"newspaper\" href=\"/integrations/news/2026/v18.2.1\" horizontal>\n Bug fix for build command with symlink-based package managers\n\n *Released: 2026-02-23*\n</Card>\n\n<Card title=\"Pushing unlabelled semantic versions must be sequential\" icon=\"newspaper\" href=\"/integrations/news/2026/no-skip-or-intermediate-versions\" horizontal>\n Unlabelled integration versions must be published in order via `zapier-platform push`.\n\n *Effective: 2026-02-23*\n</Card>\n\n<Card title=\"What's changed in v18.2.0\" icon=\"newspaper\" href=\"/integrations/news/2026/v18.2.0\" horizontal>\n invoke command supports function-based choices, stashing returns a better error message\n\n *Released: 2026-02-18*\n</Card>\n\n<Card title=\"What's changed in v18.1.1\" icon=\"newspaper\" href=\"/integrations/news/2026/v18.1.1\" horizontal>\n Bug fix for missing HTTP error logs and security updates.\n\n *Released: 2026-01-29*\n</Card>\n\n<Card title=\"What's changed in v18.1.0\" icon=\"newspaper\" href=\"/integrations/news/2026/v18.1.0\" horizontal>\n New `invoke --remote` flag and a fix on package manager detection.\n\n *Released: 2026-01-19*\n</Card>\n\n<Card title=\"What's changed in v18.0.7\" icon=\"newspaper\" href=\"/integrations/news/2026/v18.0.7\" horizontal>\n Publishing process improvements, refactoring, and `sample` field added to dynamic `outputFields`.\n\n *Released: 2026-01-07*\n</Card>\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2026/index", "source_repo": "", "source_path": "", "section": "news", "tags": ["2026", "changelog", "news"], "related": [], "meta": {"year": "2026"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2026/migrations-same-major-version", "kind": "platform_news", "key": "2026/migrations-same-major-version", "title": "User migrations must stay within the same major version", "summary": "User migrations must stay within the same major version", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# User migrations must stay within the same major version\n\n> The Platform UI and CLI now block migrating users when the source and target integration versions differ in their [semantic major version](/integrations/manage/versions#version-numbering)—for example, you cannot migrate from `1.x.x` to `2.x.x`.\n\n*Effective: 2026-02-26*\n\n## Same-major-version migrations only\n\n* Migrations are only allowed when the **from** and **to** versions share the same major number (e.g. `1.0.0` → `1.0.1`, or `2.1.0` → `2.2.0`).\n* Cross-major moves (e.g. `1.5.0` → `2.0.0`) are blocked in both the [Platform UI](https://zapier.com/app/developer) and via [`zapier-platform migrate`](https://github.com/zapier/zapier-platform/blob/main/packages/cli/docs/cli.md#migrate). This aligns with long-standing guidance; major releases include [breaking changes](/integrations/manage/planning-changes), so users should [update Zap workflows manually](https://help.zapier.com/hc/en-us/articles/18755649454989-App-versions-in-Zapier) or you should use [deprecation](/integrations/manage/versions#deprecating-versions) instead of migration.\n* Details and workflow are in [Migrate users to a new version](/integrations/manage/migrate).\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2026/migrations-same-major-version", "source_repo": "", "source_path": "", "section": "news", "tags": ["2026", "changelog", "news"], "related": [], "meta": {"year": "2026"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2026/no-skip-or-intermediate-versions", "kind": "platform_news", "key": "2026/no-skip-or-intermediate-versions", "title": "Pushing unlabelled semantic versions must be sequential", "summary": "Pushing unlabelled semantic versions must be sequential", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# Pushing unlabelled semantic versions must be sequential\n\n> Unlabelled integration versions must be published in order via `zapier-platform push`.\n\n*Effective: 2026-02-23*\n\n## What changed\n\nThese rules apply to **unlabelled** [semantic versions](/integrations/manage/versions#version-numbering) only (for example `1.2.3`). **[Labelled versions](/integrations/manage/labeled-versions)** (such as `1.2.3-beta` or `0.0.0-my-feature`) are not part of these checks.\n\nWhen you push a new unlabelled version, the platform validates **two** things in addition to existing format checks.\n\n### 1. You cannot skip a required predecessor\n\nThe API must see the right **previous** unlabelled release before it accepts the new one:\n\n* **Patch bump** (`1.2.3`): the exact unlabelled `1.2.2` must already exist.\n* **Minor bump** (`1.3.0`): at least one unlabelled `1.2.x` must exist.\n* **Major bump** (`2.0.0` when coming from `1.x`): at least one unlabelled `1.x.x` must exist.\n\n`1.0.0` is unchanged: there is no prior semver to require.\n\nIf the predecessor is missing, push fails with **403** and guidance like: *Version X requires Y to exist. Push version Y, then try again.*\n\n### 2. You cannot insert an “intermediate” version behind a newer line\n\nYou also cannot push a version if a **newer** unlabelled version already exists in the segment that would make yours a backward insert:\n\n* **`1.2.3`**: blocked if any unlabelled **`1.2.4` or higher** on the same `1.2.*` line already exists. Pushing **`1.3.0`** is still allowed when only `1.3.x` or `2.x.x` exists—those are not on the `1.2.*` patch line.\n* **`1.3.0`**: blocked if any unlabelled **`1.4.x` or higher** on the same major (`1.*`) already exists. **`2.0.0`** is still allowed when only `2.x.x` exists.\n* **`2.0.0`**: blocked if any unlabelled **`3.x.x` or higher** already exists.\n\nIf that applies, push fails with **403** and a message that an existing version would make this an intermediate release, which is not allowed.\n\n## What this means for you\n\n* Plan **patch → patch → minor → major** (or the minimal chain your history needs) using **unlabelled** semver when you are ready to record real releases; use **labelled** snapshots while iterating.\n* If you are stuck because old versions were removed, you may still use **[deprecation](/integrations/manage/versions#deprecating-versions)** and, when appropriate, **[delete a deprecated version](/integrations/manage/deprecate#deleting-deprecated-versions)** so your remaining unlabelled history matches what you want to push next.\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2026/no-skip-or-intermediate-versions", "source_repo": "", "source_path": "", "section": "news", "tags": ["2026", "changelog", "news"], "related": [], "meta": {"year": "2026"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2026/v18.0.7", "kind": "platform_news", "key": "2026/v18.0.7", "title": "What's changed in v18.0.7", "summary": "What's changed in v18.0.7", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v18.0.7\n\n> Publishing process improvements, refactoring, and `sample` field added to dynamic `outputFields`.\n\n*Released: 2026-01-07*\n\nIn response to the previous [Shai-Hulud incident](/integrations/build-cli/inc-547), we're changing our package publishing process to improve security. This release also includes a schema extension that allows `outputFields` to have a `sample` field. Lastly, we've refactored the `invoke` command to make upcoming enhancements easier.\n\n## cli\n\n* 🔨 Refactor `invoke` command ([#1217](https://github.com/zapier/zapier-platform/pull/1217))\n\n## core\n\nNone!\n\n## schema\n\n* 🎉 Allow a `sample` field to be provided for dynamic `outputFields` ([#1211](https://github.com/zapier/zapier-platform/pull/1211))\n\n## misc\n\n* 🔨 Add publish job in CI ([#1212](https://github.com/zapier/zapier-platform/pull/1212), [#1223](https://github.com/zapier/zapier-platform/pull/1223))\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2026/v18.0.7", "source_repo": "", "source_path": "", "section": "news", "tags": ["2026", "changelog", "news"], "related": [], "meta": {"year": "2026"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2026/v18.1.0", "kind": "platform_news", "key": "2026/v18.1.0", "title": "What's changed in v18.1.0", "summary": "What's changed in v18.1.0", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v18.1.0\n\n> New `invoke --remote` flag and a fix on package manager detection.\n\n*Released: 2026-01-19*\n\nThe `zapier-platform invoke` command now supports a **remote mode**. By adding a `--remote` (`-r` for short) flag to the `invoke` command, such as:\n\n```\nzapier-platform invoke -r\n```\n\n... all invocations, including trigger/action invocation itself, input field definitions, and dynamic dropdown choices, will be executed remotely by the Zapier production environment. This means:\n\n* The integration version you want to test has to be deployed first.\n* The invocation results and the bundle payload passed to your integration code will match what you see in live production, which is great for testing.\n* Remote mode is slower than local mode (without the `-r` flag).\n\nRead more about the three different modes in the [`zapier-platform invoke --help`](https://github.com/zapier/zapier-platform/blob/main/packages/cli/docs/cli.md#invoke) documentation.\n\nWe also fixed an issue where the `build` and `test` commands were not correctly detecting package managers (like npm, yarn, pnpm, or bun) when your integration was part of a monorepo. Now, the CLI doesn't just look in the current directory for package manager indicators (like `package-lock.json` for npm), but also checks parent directories up to four levels up.\n\n## cli\n\n* 🎉 Add `--remote` flag to `invoke` command ([#1220](https://github.com/zapier/zapier-platform/pull/1220))\n* 🐛 Fix package manager detection in `build` and `test` commands to include parent directories ([#1225](https://github.com/zapier/zapier-platform/pull/1225))\n\n## core\n\nNone!\n\n## schema\n\nNone!\n\n## misc\n\n* 📜 Improve internal development docs ([#1221](https://github.com/zapier/zapier-platform/pull/1221))\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2026/v18.1.0", "source_repo": "", "source_path": "", "section": "news", "tags": ["2026", "changelog", "news"], "related": [], "meta": {"year": "2026"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2026/v18.1.1", "kind": "platform_news", "key": "2026/v18.1.1", "title": "What's changed in v18.1.1", "summary": "What's changed in v18.1.1", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v18.1.1\n\n> Bug fix for missing HTTP error logs and security updates.\n\n*Released: 2026-01-29*\n\nMain change introduced here is fixing missing HTTP error logs that were prematurely lost during a Lambda invocation.\n\n## cli\n\nNone!\n\n## core\n\n* 🐛 Restore missing HTTP error logs ([#1227](https://github.com/zapier/zapier-platform/pull/1227))\n\n## schema\n\nNone!\n\n## misc\n\n* 🔨 Bump lodash from 4.17.21 to 4.17.23 across the board ([#1228](https://github.com/zapier/zapier-platform/pull/1228), [#1229](https://github.com/zapier/zapier-platform/pull/1229), [#1230](https://github.com/zapier/zapier-platform/pull/1230), [#1231](https://github.com/zapier/zapier-platform/pull/1231), [#1233](https://github.com/zapier/zapier-platform/pull/1233), [#1234](https://github.com/zapier/zapier-platform/pull/1234), [#1235](https://github.com/zapier/zapier-platform/pull/1235))\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2026/v18.1.1", "source_repo": "", "source_path": "", "section": "news", "tags": ["2026", "changelog", "news"], "related": [], "meta": {"year": "2026"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2026/v18.2.0", "kind": "platform_news", "key": "2026/v18.2.0", "title": "What's changed in v18.2.0", "summary": "What's changed in v18.2.0", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v18.2.0\n\n> invoke command supports function-based choices, stashing returns a better error message\n\n*Released: 2026-02-18*\n\nThe main change in this release is to support function-based choices in the `invoke` command, which will allow developers to test perform-based dynamic dropdowns.\n\n## cli\n\n* 🎉 `zapier-platform invoke` now supports function-based choices ([#1237](https://github.com/zapier/zapier-platform/pull/1237))\n\n## core\n\n* 🐛 If we attempt to stash a large response but it's bigger than the max limit, throw a descriptive error with the actual size and the limit ([#1238](https://github.com/zapier/zapier-platform/pull/1238))\n* 🔨 Add an environment variable to allow suppressing cleaning up env vars ([#1242](https://github.com/zapier/zapier-platform/pull/1242))\n\n## schema\n\nNone!\n\n## misc\n\n* 🔨 CI: Use `environment` to publish ([#1239](https://github.com/zapier/zapier-platform/pull/1239))\n* 🔨 CI: Automate the boilerplate upload ([#1240](https://github.com/zapier/zapier-platform/pull/1240))\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2026/v18.2.0", "source_repo": "", "source_path": "", "section": "news", "tags": ["2026", "changelog", "news"], "related": [], "meta": {"year": "2026"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2026/v18.2.1", "kind": "platform_news", "key": "2026/v18.2.1", "title": "What's changed in v18.2.1", "summary": "What's changed in v18.2.1", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v18.2.1\n\n> Bug fix for build command with symlink-based package managers\n\n*Released: 2026-02-23*\n\nResolved a bug in the CLI that caused the `build` command to fail when using a symlink-based package manager (like pnpm).\n\n## cli\n\n* 🐛 `zapier-platform build` no longer raises `EEXIST` when using a symlink-based package manager ([#1244](https://github.com/zapier/zapier-platform/pull/1244))\n\n## core\n\nNone!\n\n## schema\n\nNone!\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2026/v18.2.1", "source_repo": "", "source_path": "", "section": "news", "tags": ["2026", "changelog", "news"], "related": [], "meta": {"year": "2026"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2026/v18.2.2", "kind": "platform_news", "key": "2026/v18.2.2", "title": "What's changed in v18.2.2", "summary": "What's changed in v18.2.2", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v18.2.2\n\n> Bug fix for legacy-scripting-runner module loading\n\n*Released: 2026-02-26*\n\nImproved error handling when loading the legacy-scripting-runner module in core. The runtime now logs a warning with the actual error message when the module is installed but fails to load, making it easier to diagnose issues like missing transitive dependencies.\n\n## cli\n\nNone!\n\n## core\n\n* 🐛 Log a warning when `zapier-platform-legacy-scripting-runner` is installed but fails to load, instead of silently returning null ([#1247](https://github.com/zapier/zapier-platform/pull/1247))\n\n## schema\n\nNone!\n\n## misc\n\n* 🔨 Fix publishing workflow to run on pushes to `main` ([#1243](https://github.com/zapier/zapier-platform/pull/1243))\n* 🔨 Add non-interactive mode to bump script ([#1249](https://github.com/zapier/zapier-platform/pull/1249))\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2026/v18.2.2", "source_repo": "", "source_path": "", "section": "news", "tags": ["2026", "changelog", "news"], "related": [], "meta": {"year": "2026"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2026/v18.2.3", "kind": "platform_news", "key": "2026/v18.2.3", "title": "What's changed in v18.2.3", "summary": "What's changed in v18.2.3", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v18.2.3\n\n> Bug fixes and improvements\n\n*Released: 2026-03-04*\n\nBug fixes for the CLI build command and pnpm compatibility.\n\n## cli\n\n* 🐛 Surface package manager errors in `build` command ([#1254](https://github.com/zapier/zapier-platform/pull/1254))\n\n## core\n\n* 🐛 Declare `zapier-platform-legacy-scripting-runner` as an optional peer dep to fix pnpm strict module resolution ([#1255](https://github.com/zapier/zapier-platform/pull/1255))\n\n## schema\n\nNone!\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2026/v18.2.3", "source_repo": "", "source_path": "", "section": "news", "tags": ["2026", "changelog", "news"], "related": [], "meta": {"year": "2026"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2026/v18.3.0", "kind": "platform_news", "key": "2026/v18.3.0", "title": "What's changed in v18.3.0", "summary": "What's changed in v18.3.0", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v18.3.0\n\n> Bug fixes and improvements\n\n*Released: 2026-03-12*\n\nAdd support for function-based dynamic dropdowns\n\n## cli\n\n* 🎉 Add support for function-based dynamic dropdown to the invoke command ([#1206](https://github.com/zapier/zapier-platform/pull/1206))\n\n## core\n\nNone!\n\n## schema\n\n* 🎉 Add FieldDynamicChoicesSchema for function-based dynamic dropdowns ([#1206](https://github.com/zapier/zapier-platform/pull/1206))\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2026/v18.3.0", "source_repo": "", "source_path": "", "section": "news", "tags": ["2026", "changelog", "news"], "related": [], "meta": {"year": "2026"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2026/v18.4.0", "kind": "platform_news", "key": "2026/v18.4.0", "title": "What's changed in v18.4.0", "summary": "What's changed in v18.4.0", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v18.4.0\n\n> JSON input field type, `versions` command improvements, function-based dynamic dropdown fix\n\n*Released: 2026-04-06*\n\nThis release introduces the new `json` input field type, improved `zapier versions` output, and a schema validation fix.\n\nYou can now accept structured JSON input from users with the new [`json` field type](/integrations/build-cli/input-fields#json-fields). Optionally provide a `schema` to validate and describe the expected shape:\n\n```javascript theme={null}\n{\n key: 'product',\n type: 'json',\n label: 'Product',\n helpText: 'Enter a JSON object',\n schema: {\n type: 'object',\n properties: {\n name: { type: 'string' },\n price: { type: 'integer' },\n },\n required: ['name'],\n },\n}\n```\n\nWe also fixed a bug where pushing code with [function-based dynamic dropdowns](/integrations/build-cli/dynamic-dropdowns#function-based-dynamic-dropdowns-perform) caused an unexpected validation error on the server. If you want to use function-based dynamic dropdowns, upgrade to 18.4.0 or later:\n\n```javascript theme={null}\n{\n key: 'project_id',\n label: 'Project',\n type: 'string',\n required: true,\n choices: {\n perform: async (z, bundle) => {\n const response = await z.request('https://api.example.com/projects');\n return {\n results: response.data.map((project) => ({\n id: project.id,\n label: project.name,\n })),\n paging_token: null,\n };\n },\n },\n}\n```\n\n## cli\n\n* 💅 Clarify `zapier-platform versions` timestamps with separate \"Created at\" and \"Updated at\" columns ([#1275](https://github.com/zapier/zapier-platform/pull/1275))\n\n## core\n\n* 🎉 Add JSON field type handling with schema-aware TypeScript inference ([#1273](https://github.com/zapier/zapier-platform/pull/1273))\n\n## schema\n\n* 🎉 Add JSON input field type with optional `schema` property for structured data ([#1265](https://github.com/zapier/zapier-platform/pull/1265))\n* 🎉 Validate `schema` property on JSON fields against JSON Schema meta-schema ([#1267](https://github.com/zapier/zapier-platform/pull/1267))\n* 🐛 Fix oneOf ambiguity in FieldChoicesSchema that caused server-side validation errors for function-based dynamic dropdowns ([#1268](https://github.com/zapier/zapier-platform/pull/1268))\n* 📜 Update `skipThrowForStatus` documentation to note 401 errors are not subject to the flag ([#1270](https://github.com/zapier/zapier-platform/pull/1270))\n\n## misc\n\n* 🔨 Improve publish workflow with path filters and boilerplate build fixes ([#1264](https://github.com/zapier/zapier-platform/pull/1264), [#1266](https://github.com/zapier/zapier-platform/pull/1266))\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2026/v18.4.0", "source_repo": "", "source_path": "", "section": "news", "tags": ["2026", "changelog", "news"], "related": [], "meta": {"year": "2026"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2026/v18.5.0", "kind": "platform_news", "key": "2026/v18.5.0", "title": "What's changed in v18.5.0", "summary": "What's changed in v18.5.0", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v18.5.0\n\n> Line item support in `invoke`, falsy value fixes, new `line-items` project template\n\n*Released: 2026-04-16*\n\nThis release adds line item support to the `zapier-platform invoke` command and bumps `lodash` across all packages to address a security vulnerability.\n\n[Line items](/integrations/build-cli/input-fields#line-items) are fields with a `children` property that represent structured, repeating data — like rows in a spreadsheet or items in an order. The `invoke` command now supports them in both interactive and non-interactive modes:\n\n```bash theme={null}\n# Non-interactive: pass line items as JSON\nzapier-platform invoke create order --non-interactive \\\n -i '{\"name\": \"My Order\", \"line_items\": [{\"product_name\": \"Pens\", \"quantity\": \"12\", \"price\": \"1.50\"}]}'\n\n# Interactive: use the line item editing UI\nzapier-platform invoke create order -i '{\"name\": \"My Order\"}'\n```\n\nIn interactive mode, a sub-menu lets you add, edit, and delete items with per-field editing and required field validation.\n\n## cli\n\n* 🎉 Add line item support to `invoke` command with interactive editing UI ([#1272](https://github.com/zapier/zapier-platform/pull/1272))\n* 🎉 Add `line-items` project template for `zapier-platform init` ([#1272](https://github.com/zapier/zapier-platform/pull/1272))\n* 🐛 Fix `invoke` bugs: auto-detect auth ID for no-auth apps in remote mode, falsy value handling (`0`, `false`) causing infinite dropdown re-prompting, and more ([#1272](https://github.com/zapier/zapier-platform/pull/1272))\n* 🔨 Bump `lodash` from 4.17.23 to 4.18.1 ([#1274](https://github.com/zapier/zapier-platform/pull/1274))\n\n## core\n\n* 🔨 Bump `lodash` from 4.17.23 to 4.18.1 ([#1274](https://github.com/zapier/zapier-platform/pull/1274))\n\n## schema\n\n* 🔨 Bump `lodash` from 4.17.23 to 4.18.1 ([#1274](https://github.com/zapier/zapier-platform/pull/1274))\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2026/v18.5.0", "source_repo": "", "source_path": "", "section": "news", "tags": ["2026", "changelog", "news"], "related": [], "meta": {"year": "2026"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2026/v18.5.1", "kind": "platform_news", "key": "2026/v18.5.1", "title": "What's changed in v18.5.1", "summary": "What's changed in v18.5.1", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v18.5.1\n\n> Actionable error when app definition fails to load, `platformData` removed from bundle, docs and `help` updated to use `zapier-platform` binary name\n\n*Released: 2026-04-30*\n\nThis patch release improves the error message you get when an app definition fails to load, removes `platformData` from the bundle, and finishes the rename of the CLI binary from `zapier` to `zapier-platform` across docs and the `help` command.\n\nWe're renaming `zapier` to `zapier-platform` because the `zapier` binary name will be allocated to the [Zapier SDK](https://docs.zapier.com/sdk). The `zapier` binary still works in v18, but in the next major release (v19), we'll officially remove it — you'll need to use `zapier-platform` instead. If `zapier-platform` is too long to type, you can set up a shell alias like `alias zp=zapier-platform`.\n\n## cli\n\n* 📜 Rename binary name from `zapier` to `zapier-platform` in docs, source, and `help` command ([#1291](https://github.com/zapier/zapier-platform/pull/1291), [#1292](https://github.com/zapier/zapier-platform/pull/1292), [#1293](https://github.com/zapier/zapier-platform/pull/1293))\n\n## core\n\n* 🐛 Throw actionable error when app definition fails to load ([#1288](https://github.com/zapier/zapier-platform/pull/1288))\n* 🐛 Remove `platformData` from bundle logging ([#1289](https://github.com/zapier/zapier-platform/pull/1289))\n\n## schema\n\nNone!\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2026/v18.5.1", "source_repo": "", "source_path": "", "section": "news", "tags": ["2026", "changelog", "news"], "related": [], "meta": {"year": "2026"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2026/v18.6.0", "kind": "platform_news", "key": "2026/v18.6.0", "title": "What's changed in v18.6.0", "summary": "What's changed in v18.6.0", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v18.6.0\n\n> New `invoke auth template` and `invoke auth render` commands for inspecting an app's auth request shape\n\n*Released: 2026-05-05*\n\nThis release adds two new commands that let you inspect and render the authentication request your app produces. They run your app's middleware (`beforeRequest`, `getAccessToken`, etc.) with placeholder credentials and capture the resulting auth request shape (headers, query params, and body) without making a real network call.\n\n`zapier-platform invoke auth template` returns the static template (with `{{placeholders}}` for auth fields). `zapier-platform invoke auth render` substitutes real auth data from .env into that template and returns the final request.\n\n## cli\n\n* 🎉 Add `invoke auth template` and `invoke auth render` commands ([#1282](https://github.com/zapier/zapier-platform/pull/1282))\n\n## core\n\n* 🎉 Add `getAuthTemplate` and `renderAuthTemplate` Lambda commands ([#1282](https://github.com/zapier/zapier-platform/pull/1282))\n\n## schema\n\nNone!\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2026/v18.6.0", "source_repo": "", "source_path": "", "section": "news", "tags": ["2026", "changelog", "news"], "related": [], "meta": {"year": "2026"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2026/v19.0.0", "kind": "platform_news", "key": "2026/v19.0.0", "title": "What's changed in v19.0.0", "summary": "What's changed in v19.0.0", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v19.0.0\n\n> The `zapier` CLI binary has been removed. Use `zapier-platform` instead.\n\n*Released: 2026-05-18*\n\nVersion 19.0.0 is a **BREAKING CHANGE** release. Here is a brief breakdown of the main change (**❗ denotes a breaking change**):\n\n## ❗ The `zapier` binary has been removed\n\nThe `zapier` command was deprecated in v18.0.0 in favor of `zapier-platform`. v19 completes that transition by removing the old binary entirely.\n\n***\n\nApart from this major change, here are the detailed release notes for this release (**note that ❗ denotes a breaking change**):\n\n## cli\n\n* ❗ Remove the `zapier` executable; the CLI now ships only `zapier-platform` ([#1299](https://github.com/zapier/zapier-platform/pull/1299))\n\n## core\n\nNone!\n\n## schema\n\nNone!\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2026/v19.0.0", "source_repo": "", "source_path": "", "section": "news", "tags": ["2026", "changelog", "news"], "related": [], "meta": {"year": "2026"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2026/v19.1.0", "kind": "platform_news", "key": "2026/v19.1.0", "title": "What's changed in v19.1.0", "summary": "What's changed in v19.1.0", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# What's changed in v19.1.0\n\n> Auth template rendering can honor the real outbound request and custom request properties, plus a fix for the `appTester` type signature\n\n*Released: 2026-07-30*\n\nThis release improves auth template extraction and rendering: templates can now honor the real outbound request and integration-specific custom request properties when selecting credentials, non-auth request bodies are kept out of extracted templates, and `z.request(url, options)` calls are handled correctly during extraction. It also fixes the `appTester` TypeScript signature to accept request templates.\n\n## cli\n\nNone!\n\n## core\n\n* Thread `targetRequest` through `renderAuthTemplate` so rendering can honor the real outbound request ([#1298](https://github.com/zapier/zapier-platform/pull/1298))\n* Support `customRequestProperties` in the `renderAuthTemplate` bundle, letting integration middleware select the right credential during rendering ([#1322](https://github.com/zapier/zapier-platform/pull/1322))\n* Drop non-auth request bodies from extracted auth templates ([#1323](https://github.com/zapier/zapier-platform/pull/1323))\n* Preserve `z.request(url, options)` options in auth-template request stubs, and honor `customRequestProperties` during template extraction ([#1324](https://github.com/zapier/zapier-platform/pull/1324))\n* Support request templates in the `appTester` type signature ([#1302](https://github.com/zapier/zapier-platform/pull/1302))\n\n## schema\n\nNone!\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2026/v19.1.0", "source_repo": "", "source_path": "", "section": "news", "tags": ["2026", "changelog", "news"], "related": [], "meta": {"year": "2026"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2026/version-promotion-guardrails", "kind": "platform_news", "key": "2026/version-promotion-guardrails", "title": "New platform guardrails for safer integration versioning", "summary": "New platform guardrails for safer integration versioning", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# New platform guardrails for safer integration versioning\n\n> The platform now checks for breaking changes during promotion and guides you toward the correct semantic version, helping protect your users from unexpected disruptions.\n\n*Effective: 2026-05-12*\n\n## What's new\n\nThe platform now automatically checks for breaking changes when you [promote](/integrations/manage/promote) a new integration version. If breaking changes are found and the version doesn't increment the major number, promotion is paused with a clear explanation of what was detected and which version number to use instead.\n\nThis helps you catch issues **before** they reach users — no more accidentally shipping a removal or auth change under a patch bump.\n\n## What gets checked\n\nWhen you promote, the platform compares the new version against the current public version at the **schema level** — looking at the structure of your triggers, actions, searches, and authentication. The following schema-level breaking changes are detected automatically:\n\n* **Removed triggers, actions, or searches** — a key present in the current public version is missing in the new version\n* **Authentication type change** — the auth type (e.g., `oauth2`, `apiKey`, `session`) differs between versions\n* **Trigger type change** — a trigger switched between polling and hook type\n* **Removed searchOrCreate keys** — a searchOrCreate present in the current version is missing\n* **Removed input field keys** — an input field key on an existing trigger/action was removed\n* **Optional input field made required without a default** — an existing optional field is now required but has no default value\n* **Authentication field changes** — removing an auth field, adding a new required auth field, or changing an auth field's type\n* **Input field type changes** — changing the type of an input field (e.g., `string` → `list`)\n* **Incompatible JSON field schema changes** — backward-incompatible changes to `json`-type input field schemas\n\nIf any of these are detected, you'll see a message explaining the specific changes found and the minimum major version required.\n\n<Note>\n These checks cover **schema-level** changes only. Some breaking changes happen outside the schema — for example, removing or renaming output field keys, changing the behavior of a perform function, or altering response structures. These are still your responsibility to catch. Review the full [versioning matrix](/integrations/manage/planning-changes) before promoting.\n</Note>\n\n## What this means for you\n\n* **If you're already following semver**, nothing changes. You're good.\n* **If a promotion is paused**, read the message — it tells you exactly which changes triggered the check and what version number to use. Bump the major version and promote again.\n* **If you need to phase out a trigger, action, or search without a major bump**, [hide it](/integrations/manage/versions#what-counts-as-a-breaking-change) instead of removing it. Hidden items continue to work for existing Zap workflows but are no longer available to new users.\n\nFor the full list of what gets detected and how to choose the right version number, see [Version numbering](/integrations/manage/versions#version-numbering).\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2026/version-promotion-guardrails", "source_repo": "", "source_path": "", "section": "news", "tags": ["2026", "changelog", "news"], "related": [], "meta": {"year": "2026"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:2026", "kind": "platform_news", "key": "2026", "title": "Platform News in 2026", "summary": "Platform News in 2026", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# Platform News in 2026\n\n<Card title=\"What's changed in v19.1.0\" icon=\"newspaper\" href=\"/integrations/news/2026/v19.1.0\" horizontal>\n Auth template rendering can honor the real outbound request and custom request properties, plus a fix for the `appTester` type signature\n\n *Released: 2026-07-30*\n</Card>\n\n<Card title=\"What's changed in v19.0.0\" icon=\"newspaper\" href=\"/integrations/news/2026/v19.0.0\" horizontal>\n The `zapier` CLI binary has been removed. Use `zapier-platform` instead.\n\n *Released: 2026-05-18*\n</Card>\n\n<Card title=\"New platform guardrails for safer integration versioning\" icon=\"newspaper\" href=\"/integrations/news/2026/version-promotion-guardrails\" horizontal>\n The platform now checks for breaking changes during promotion and guides you toward the correct semantic version, helping protect your users from unexpected disruptions.\n\n *Effective: 2026-05-12*\n</Card>\n\n<Card title=\"What's changed in v18.6.0\" icon=\"newspaper\" href=\"/integrations/news/2026/v18.6.0\" horizontal>\n New `invoke auth template` and `invoke auth render` commands for inspecting an app's auth request shape\n\n *Released: 2026-05-05*\n</Card>\n\n<Card title=\"What's changed in v18.5.1\" icon=\"newspaper\" href=\"/integrations/news/2026/v18.5.1\" horizontal>\n Actionable error when app definition fails to load, `platformData` removed from bundle, docs and `help` updated to use `zapier-platform` binary name\n\n *Released: 2026-04-30*\n</Card>\n\n<Card title=\"What's changed in v18.5.0\" icon=\"newspaper\" href=\"/integrations/news/2026/v18.5.0\" horizontal>\n Line item support in `invoke`, falsy value fixes, new `line-items` project template\n\n *Released: 2026-04-16*\n</Card>\n\n<Card title=\"What's changed in v18.4.0\" icon=\"newspaper\" href=\"/integrations/news/2026/v18.4.0\" horizontal>\n JSON input field type, `versions` command improvements, function-based dynamic dropdown fix\n\n *Released: 2026-04-06*\n</Card>\n\n<Card title=\"What's changed in v18.3.0\" icon=\"newspaper\" href=\"/integrations/news/2026/v18.3.0\" horizontal>\n Bug fixes and improvements\n\n *Released: 2026-03-12*\n</Card>\n\n<Card title=\"What's changed in v18.2.3\" icon=\"newspaper\" href=\"/integrations/news/2026/v18.2.3\" horizontal>\n Bug fixes and improvements\n\n *Released: 2026-03-04*\n</Card>\n\n<Card title=\"What's changed in v18.2.2\" icon=\"newspaper\" href=\"/integrations/news/2026/v18.2.2\" horizontal>\n Bug fix for legacy-scripting-runner module loading\n\n *Released: 2026-02-26*\n</Card>\n\n<Card title=\"User migrations must stay within the same major version\" icon=\"newspaper\" href=\"/integrations/news/2026/migrations-same-major-version\" horizontal>\n The Platform UI and CLI now block migrating users when the source and target integration versions differ in their [semantic major version](/integrations/manage/versions#version-numbering)—for example, you cannot migrate from `1.x.x` to `2.x.x`.\n\n *Effective: 2026-02-26*\n</Card>\n\n<Card title=\"What's changed in v18.2.1\" icon=\"newspaper\" href=\"/integrations/news/2026/v18.2.1\" horizontal>\n Bug fix for build command with symlink-based package managers\n\n *Released: 2026-02-23*\n</Card>\n\n<Card title=\"Pushing unlabelled semantic versions must be sequential\" icon=\"newspaper\" href=\"/integrations/news/2026/no-skip-or-intermediate-versions\" horizontal>\n Unlabelled integration versions must be published in order via `zapier-platform push`.\n\n *Effective: 2026-02-23*\n</Card>\n\n<Card title=\"What's changed in v18.2.0\" icon=\"newspaper\" href=\"/integrations/news/2026/v18.2.0\" horizontal>\n invoke command supports function-based choices, stashing returns a better error message\n\n *Released: 2026-02-18*\n</Card>\n\n<Card title=\"What's changed in v18.1.1\" icon=\"newspaper\" href=\"/integrations/news/2026/v18.1.1\" horizontal>\n Bug fix for missing HTTP error logs and security updates.\n\n *Released: 2026-01-29*\n</Card>\n\n<Card title=\"What's changed in v18.1.0\" icon=\"newspaper\" href=\"/integrations/news/2026/v18.1.0\" horizontal>\n New `invoke --remote` flag and a fix on package manager detection.\n\n *Released: 2026-01-19*\n</Card>\n\n<Card title=\"What's changed in v18.0.7\" icon=\"newspaper\" href=\"/integrations/news/2026/v18.0.7\" horizontal>\n Publishing process improvements, refactoring, and `sample` field added to dynamic `outputFields`.\n\n *Released: 2026-01-07*\n</Card>\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/2026", "source_repo": "", "source_path": "", "section": "news", "tags": ["changelog", "news"], "related": [], "meta": {"year": "2026.md"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "platform_news:single-page", "kind": "platform_news", "key": "single-page", "title": "Platform News (Single Page)", "summary": "Platform News (Single Page)", "body": "> ## Documentation Index\n> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt\n> Use this file to discover all available pages before exploring further.\n\n# Platform News (Single Page)\n\n> Recent changelogs and tips on a single page\n\n## What's changed in v19.1.0\n\n*Released: 2026-07-30*\n\nThis release improves auth template extraction and rendering: templates can now honor the real outbound request and integration-specific custom request properties when selecting credentials, non-auth request bodies are kept out of extracted templates, and `z.request(url, options)` calls are handled correctly during extraction. It also fixes the `appTester` TypeScript signature to accept request templates.\n\n**cli**\n\nNone!\n\n**core**\n\n* Thread `targetRequest` through `renderAuthTemplate` so rendering can honor the real outbound request ([#1298](https://github.com/zapier/zapier-platform/pull/1298))\n* Support `customRequestProperties` in the `renderAuthTemplate` bundle, letting integration middleware select the right credential during rendering ([#1322](https://github.com/zapier/zapier-platform/pull/1322))\n* Drop non-auth request bodies from extracted auth templates ([#1323](https://github.com/zapier/zapier-platform/pull/1323))\n* Preserve `z.request(url, options)` options in auth-template request stubs, and honor `customRequestProperties` during template extraction ([#1324](https://github.com/zapier/zapier-platform/pull/1324))\n* Support request templates in the `appTester` type signature ([#1302](https://github.com/zapier/zapier-platform/pull/1302))\n\n**schema**\n\nNone!\n\n***\n\n## What's changed in v19.0.0\n\n*Released: 2026-05-18*\n\nVersion 19.0.0 is a **BREAKING CHANGE** release. Here is a brief breakdown of the main change (**❗ denotes a breaking change**):\n\n**❗ The `zapier` binary has been removed**\n\nThe `zapier` command was deprecated in v18.0.0 in favor of `zapier-platform`. v19 completes that transition by removing the old binary entirely.\n\n***\n\nApart from this major change, here are the detailed release notes for this release (**note that ❗ denotes a breaking change**):\n\n**cli**\n\n* ❗ Remove the `zapier` executable; the CLI now ships only `zapier-platform` ([#1299](https://github.com/zapier/zapier-platform/pull/1299))\n\n**core**\n\nNone!\n\n**schema**\n\nNone!\n\n***\n\n## New platform guardrails for safer integration versioning\n\n*Effective: 2026-05-12*\n\n**What's new**\n\nThe platform now automatically checks for breaking changes when you [promote](/integrations/manage/promote) a new integration version. If breaking changes are found and the version doesn't increment the major number, promotion is paused with a clear explanation of what was detected and which version number to use instead.\n\nThis helps you catch issues **before** they reach users — no more accidentally shipping a removal or auth change under a patch bump.\n\n**What gets checked**\n\nWhen you promote, the platform compares the new version against the current public version at the **schema level** — looking at the structure of your triggers, actions, searches, and authentication. The following schema-level breaking changes are detected automatically:\n\n* **Removed triggers, actions, or searches** — a key present in the current public version is missing in the new version\n* **Authentication type change** — the auth type (e.g., `oauth2`, `apiKey`, `session`) differs between versions\n* **Trigger type change** — a trigger switched between polling and hook type\n* **Removed searchOrCreate keys** — a searchOrCreate present in the current version is missing\n* **Removed input field keys** — an input field key on an existing trigger/action was removed\n* **Optional input field made required without a default** — an existing optional field is now required but has no default value\n* **Authentication field changes** — removing an auth field, adding a new required auth field, or changing an auth field's type\n* **Input field type changes** — changing the type of an input field (e.g., `string` → `list`)\n* **Incompatible JSON field schema changes** — backward-incompatible changes to `json`-type input field schemas\n\nIf any of these are detected, you'll see a message explaining the specific changes found and the minimum major version required.\n\n<Note>\n These checks cover **schema-level** changes only. Some breaking changes happen outside the schema — for example, removing or renaming output field keys, changing the behavior of a perform function, or altering response structures. These are still your responsibility to catch. Review the full [versioning matrix](/integrations/manage/planning-changes) before promoting.\n</Note>\n\n**What this means for you**\n\n* **If you're already following semver**, nothing changes. You're good.\n* **If a promotion is paused**, read the message — it tells you exactly which changes triggered the check and what version number to use. Bump the major version and promote again.\n* **If you need to phase out a trigger, action, or search without a major bump**, [hide it](/integrations/manage/versions#what-counts-as-a-breaking-change) instead of removing it. Hidden items continue to work for existing Zap workflows but are no longer available to new users.\n\nFor the full list of what gets detected and how to choose the right version number, see [Version numbering](/integrations/manage/versions#version-numbering).\n\n***\n\n## What's changed in v18.6.0\n\n*Released: 2026-05-05*\n\nThis release adds two new commands that let you inspect and render the authentication request your app produces. They run your app's middleware (`beforeRequest`, `getAccessToken`, etc.) with placeholder credentials and capture the resulting auth request shape (headers, query params, and body) without making a real network call.\n\n`zapier-platform invoke auth template` returns the static template (with `{{placeholders}}` for auth fields). `zapier-platform invoke auth render` substitutes real auth data from .env into that template and returns the final request.\n\n**cli**\n\n* 🎉 Add `invoke auth template` and `invoke auth render` commands ([#1282](https://github.com/zapier/zapier-platform/pull/1282))\n\n**core**\n\n* 🎉 Add `getAuthTemplate` and `renderAuthTemplate` Lambda commands ([#1282](https://github.com/zapier/zapier-platform/pull/1282))\n\n**schema**\n\nNone!\n\n***\n\n## What's changed in v18.5.1\n\n*Released: 2026-04-30*\n\nThis patch release improves the error message you get when an app definition fails to load, removes `platformData` from the bundle, and finishes the rename of the CLI binary from `zapier` to `zapier-platform` across docs and the `help` command.\n\nWe're renaming `zapier` to `zapier-platform` because the `zapier` binary name will be allocated to the [Zapier SDK](https://docs.zapier.com/sdk). The `zapier` binary still works in v18, but in the next major release (v19), we'll officially remove it — you'll need to use `zapier-platform` instead. If `zapier-platform` is too long to type, you can set up a shell alias like `alias zp=zapier-platform`.\n\n**cli**\n\n* 📜 Rename binary name from `zapier` to `zapier-platform` in docs, source, and `help` command ([#1291](https://github.com/zapier/zapier-platform/pull/1291), [#1292](https://github.com/zapier/zapier-platform/pull/1292), [#1293](https://github.com/zapier/zapier-platform/pull/1293))\n\n**core**\n\n* 🐛 Throw actionable error when app definition fails to load ([#1288](https://github.com/zapier/zapier-platform/pull/1288))\n* 🐛 Remove `platformData` from bundle logging ([#1289](https://github.com/zapier/zapier-platform/pull/1289))\n\n**schema**\n\nNone!\n\n***\n\n## What's changed in v18.5.0\n\n*Released: 2026-04-16*\n\nThis release adds line item support to the `zapier-platform invoke` command and bumps `lodash` across all packages to address a security vulnerability.\n\n[Line items](/integrations/build-cli/input-fields#line-items) are fields with a `children` property that represent structured, repeating data — like rows in a spreadsheet or items in an order. The `invoke` command now supports them in both interactive and non-interactive modes:\n\n```bash theme={null}\n**Non-interactive: pass line items as JSON**\nzapier-platform invoke create order --non-interactive \\\n -i '{\"name\": \"My Order\", \"line_items\": [{\"product_name\": \"Pens\", \"quantity\": \"12\", \"price\": \"1.50\"}]}'\n\n**Interactive: use the line item editing UI**\nzapier-platform invoke create order -i '{\"name\": \"My Order\"}'\n```\n\nIn interactive mode, a sub-menu lets you add, edit, and delete items with per-field editing and required field validation.\n\n**cli**\n\n* 🎉 Add line item support to `invoke` command with interactive editing UI ([#1272](https://github.com/zapier/zapier-platform/pull/1272))\n* 🎉 Add `line-items` project template for `zapier-platform init` ([#1272](https://github.com/zapier/zapier-platform/pull/1272))\n* 🐛 Fix `invoke` bugs: auto-detect auth ID for no-auth apps in remote mode, falsy value handling (`0`, `false`) causing infinite dropdown re-prompting, and more ([#1272](https://github.com/zapier/zapier-platform/pull/1272))\n* 🔨 Bump `lodash` from 4.17.23 to 4.18.1 ([#1274](https://github.com/zapier/zapier-platform/pull/1274))\n\n**core**\n\n* 🔨 Bump `lodash` from 4.17.23 to 4.18.1 ([#1274](https://github.com/zapier/zapier-platform/pull/1274))\n\n**schema**\n\n* 🔨 Bump `lodash` from 4.17.23 to 4.18.1 ([#1274](https://github.com/zapier/zapier-platform/pull/1274))\n\n***\n\n## What's changed in v18.4.0\n\n*Released: 2026-04-06*\n\nThis release introduces the new `json` input field type, improved `zapier versions` output, and a schema validation fix.\n\nYou can now accept structured JSON input from users with the new [`json` field type](/integrations/build-cli/input-fields#json-fields). Optionally provide a `schema` to validate and describe the expected shape:\n\n```javascript theme={null}\n{\n key: 'product',\n type: 'json',\n label: 'Product',\n helpText: 'Enter a JSON object',\n schema: {\n type: 'object',\n properties: {\n name: { type: 'string' },\n price: { type: 'integer' },\n },\n required: ['name'],\n },\n}\n```\n\nWe also fixed a bug where pushing code with [function-based dynamic dropdowns](/integrations/build-cli/dynamic-dropdowns#function-based-dynamic-dropdowns-perform) caused an unexpected validation error on the server. If you want to use function-based dynamic dropdowns, upgrade to 18.4.0 or later:\n\n```javascript theme={null}\n{\n key: 'project_id',\n label: 'Project',\n type: 'string',\n required: true,\n choices: {\n perform: async (z, bundle) => {\n const response = await z.request('https://api.example.com/projects');\n return {\n results: response.data.map((project) => ({\n id: project.id,\n label: project.name,\n })),\n paging_token: null,\n };\n },\n },\n}\n```\n\n**cli**\n\n* 💅 Clarify `zapier-platform versions` timestamps with separate \"Created at\" and \"Updated at\" columns ([#1275](https://github.com/zapier/zapier-platform/pull/1275))\n\n**core**\n\n* 🎉 Add JSON field type handling with schema-aware TypeScript inference ([#1273](https://github.com/zapier/zapier-platform/pull/1273))\n\n**schema**\n\n* 🎉 Add JSON input field type with optional `schema` property for structured data ([#1265](https://github.com/zapier/zapier-platform/pull/1265))\n* 🎉 Validate `schema` property on JSON fields against JSON Schema meta-schema ([#1267](https://github.com/zapier/zapier-platform/pull/1267))\n* 🐛 Fix oneOf ambiguity in FieldChoicesSchema that caused server-side validation errors for function-based dynamic dropdowns ([#1268](https://github.com/zapier/zapier-platform/pull/1268))\n* 📜 Update `skipThrowForStatus` documentation to note 401 errors are not subject to the flag ([#1270](https://github.com/zapier/zapier-platform/pull/1270))\n\n**misc**\n\n* 🔨 Improve publish workflow with path filters and boilerplate build fixes ([#1264](https://github.com/zapier/zapier-platform/pull/1264), [#1266](https://github.com/zapier/zapier-platform/pull/1266))\n\n***\n\n## What's changed in v18.3.0\n\n*Released: 2026-03-12*\n\nAdd support for function-based dynamic dropdowns\n\n**cli**\n\n* 🎉 Add support for function-based dynamic dropdown to the invoke command ([#1206](https://github.com/zapier/zapier-platform/pull/1206))\n\n**core**\n\nNone!\n\n**schema**\n\n* 🎉 Add FieldDynamicChoicesSchema for function-based dynamic dropdowns ([#1206](https://github.com/zapier/zapier-platform/pull/1206))\n\n***\n\n## What's changed in v18.2.3\n\n*Released: 2026-03-04*\n\nBug fixes for the CLI build command and pnpm compatibility.\n\n**cli**\n\n* 🐛 Surface package manager errors in `build` command ([#1254](https://github.com/zapier/zapier-platform/pull/1254))\n\n**core**\n\n* 🐛 Declare `zapier-platform-legacy-scripting-runner` as an optional peer dep to fix pnpm strict module resolution ([#1255](https://github.com/zapier/zapier-platform/pull/1255))\n\n**schema**\n\nNone!\n\n***\n\n## What's changed in v18.2.2\n\n*Released: 2026-02-26*\n\nImproved error handling when loading the legacy-scripting-runner module in core. The runtime now logs a warning with the actual error message when the module is installed but fails to load, making it easier to diagnose issues like missing transitive dependencies.\n\n**cli**\n\nNone!\n\n**core**\n\n* 🐛 Log a warning when `zapier-platform-legacy-scripting-runner` is installed but fails to load, instead of silently returning null ([#1247](https://github.com/zapier/zapier-platform/pull/1247))\n\n**schema**\n\nNone!\n\n**misc**\n\n* 🔨 Fix publishing workflow to run on pushes to `main` ([#1243](https://github.com/zapier/zapier-platform/pull/1243))\n* 🔨 Add non-interactive mode to bump script ([#1249](https://github.com/zapier/zapier-platform/pull/1249))\n\n***\n\n## User migrations must stay within the same major version\n\n*Effective: 2026-02-26*\n\n**Same-major-version migrations only**\n\n* Migrations are only allowed when the **from** and **to** versions share the same major number (e.g. `1.0.0` → `1.0.1`, or `2.1.0` → `2.2.0`).\n* Cross-major moves (e.g. `1.5.0` → `2.0.0`) are blocked in both the [Platform UI](https://zapier.com/app/developer) and via [`zapier-platform migrate`](https://github.com/zapier/zapier-platform/blob/main/packages/cli/docs/cli.md#migrate). This aligns with long-standing guidance; major releases include [breaking changes](/integrations/manage/planning-changes), so users should [update Zap workflows manually](https://help.zapier.com/hc/en-us/articles/18755649454989-App-versions-in-Zapier) or you should use [deprecation](/integrations/manage/versions#deprecating-versions) instead of migration.\n* Details and workflow are in [Migrate users to a new version](/integrations/manage/migrate).\n\n***\n\n## What's changed in v18.2.1\n\n*Released: 2026-02-23*\n\nResolved a bug in the CLI that caused the `build` command to fail when using a symlink-based package manager (like pnpm).\n\n**cli**\n\n* 🐛 `zapier-platform build` no longer raises `EEXIST` when using a symlink-based package manager ([#1244](https://github.com/zapier/zapier-platform/pull/1244))\n\n**core**\n\nNone!\n\n**schema**\n\nNone!\n\n***\n\n## Pushing unlabelled semantic versions must be sequential\n\n*Effective: 2026-02-23*\n\n**What changed**\n\nThese rules apply to **unlabelled** [semantic versions](/integrations/manage/versions#version-numbering) only (for example `1.2.3`). **[Labelled versions](/integrations/manage/labeled-versions)** (such as `1.2.3-beta` or `0.0.0-my-feature`) are not part of these checks.\n\nWhen you push a new unlabelled version, the platform validates **two** things in addition to existing format checks.\n\n**1. You cannot skip a required predecessor**\n\nThe API must see the right **previous** unlabelled release before it accepts the new one:\n\n* **Patch bump** (`1.2.3`): the exact unlabelled `1.2.2` must already exist.\n* **Minor bump** (`1.3.0`): at least one unlabelled `1.2.x` must exist.\n* **Major bump** (`2.0.0` when coming from `1.x`): at least one unlabelled `1.x.x` must exist.\n\n`1.0.0` is unchanged: there is no prior semver to require.\n\nIf the predecessor is missing, push fails with **403** and guidance like: *Version X requires Y to exist. Push version Y, then try again.*\n\n**2. You cannot insert an “intermediate” version behind a newer line**\n\nYou also cannot push a version if a **newer** unlabelled version already exists in the segment that would make yours a backward insert:\n\n* **`1.2.3`**: blocked if any unlabelled **`1.2.4` or higher** on the same `1.2.*` line already exists. Pushing **`1.3.0`** is still allowed when only `1.3.x` or `2.x.x` exists—those are not on the `1.2.*` patch line.\n* **`1.3.0`**: blocked if any unlabelled **`1.4.x` or higher** on the same major (`1.*`) already exists. **`2.0.0`** is still allowed when only `2.x.x` exists.\n* **`2.0.0`**: blocked if any unlabelled **`3.x.x` or higher** already exists.\n\nIf that applies, push fails with **403** and a message that an existing version would make this an intermediate release, which is not allowed.\n\n**What this means for you**\n\n* Plan **patch → patch → minor → major** (or the minimal chain your history needs) using **unlabelled** semver when you are ready to record real releases; use **labelled** snapshots while iterating.\n* If you are stuck because old versions were removed, you may still use **[deprecation](/integrations/manage/versions#deprecating-versions)** and, when appropriate, **[delete a deprecated version](/integrations/manage/deprecate#deleting-deprecated-versions)** so your remaining unlabelled history matches what you want to push next.\n\n***\n\n## What's changed in v18.2.0\n\n*Released: 2026-02-18*\n\nThe main change in this release is to support function-based choices in the `invoke` command, which will allow developers to test perform-based dynamic dropdowns.\n\n**cli**\n\n* 🎉 `zapier-platform invoke` now supports function-based choices ([#1237](https://github.com/zapier/zapier-platform/pull/1237))\n\n**core**\n\n* 🐛 If we attempt to stash a large response but it's bigger than the max limit, throw a descriptive error with the actual size and the limit ([#1238](https://github.com/zapier/zapier-platform/pull/1238))\n* 🔨 Add an environment variable to allow suppressing cleaning up env vars ([#1242](https://github.com/zapier/zapier-platform/pull/1242))\n\n**schema**\n\nNone!\n\n**misc**\n\n* 🔨 CI: Use `environment` to publish ([#1239](https://github.com/zapier/zapier-platform/pull/1239))\n* 🔨 CI: Automate the boilerplate upload ([#1240](https://github.com/zapier/zapier-platform/pull/1240))\n\n***\n\n## What's changed in v18.1.1\n\n*Released: 2026-01-29*\n\nMain change introduced here is fixing missing HTTP error logs that were prematurely lost during a Lambda invocation.\n\n**cli**\n\nNone!\n\n**core**\n\n* 🐛 Restore missing HTTP error logs ([#1227](https://github.com/zapier/zapier-platform/pull/1227))\n\n**schema**\n\nNone!\n\n**misc**\n\n* 🔨 Bump lodash from 4.17.21 to 4.17.23 across the board ([#1228](https://github.com/zapier/zapier-platform/pull/1228), [#1229](https://github.com/zapier/zapier-platform/pull/1229), [#1230](https://github.com/zapier/zapier-platform/pull/1230), [#1231](https://github.com/zapier/zapier-platform/pull/1231), [#1233](https://github.com/zapier/zapier-platform/pull/1233), [#1234](https://github.com/zapier/zapier-platform/pull/1234), [#1235](https://github.com/zapier/zapier-platform/pull/1235))\n\n***\n\n## What's changed in v18.1.0\n\n*Released: 2026-01-19*\n\nThe `zapier-platform invoke` command now supports a **remote mode**. By adding a `--remote` (`-r` for short) flag to the `invoke` command, such as:\n\n```\nzapier-platform invoke -r\n```\n\n... all invocations, including trigger/action invocation itself, input field definitions, and dynamic dropdown choices, will be executed remotely by the Zapier production environment. This means:\n\n* The integration version you want to test has to be deployed first.\n* The invocation results and the bundle payload passed to your integration code will match what you see in live production, which is great for testing.\n* Remote mode is slower than local mode (without the `-r` flag).\n\nRead more about the three different modes in the [`zapier-platform invoke --help`](https://github.com/zapier/zapier-platform/blob/main/packages/cli/docs/cli.md#invoke) documentation.\n\nWe also fixed an issue where the `build` and `test` commands were not correctly detecting package managers (like npm, yarn, pnpm, or bun) when your integration was part of a monorepo. Now, the CLI doesn't just look in the current directory for package manager indicators (like `package-lock.json` for npm), but also checks parent directories up to four levels up.\n\n**cli**\n\n* 🎉 Add `--remote` flag to `invoke` command ([#1220](https://github.com/zapier/zapier-platform/pull/1220))\n* 🐛 Fix package manager detection in `build` and `test` commands to include parent directories ([#1225](https://github.com/zapier/zapier-platform/pull/1225))\n\n**core**\n\nNone!\n\n**schema**\n\nNone!\n\n**misc**\n\n* 📜 Improve internal development docs ([#1221](https://github.com/zapier/zapier-platform/pull/1221))\n\n***\n\n## What's changed in v18.0.7\n\n*Released: 2026-01-07*\n\nIn response to the previous [Shai-Hulud incident](/integrations/build-cli/inc-547), we're changing our package publishing process to improve security. This release also includes a schema extension that allows `outputFields` to have a `sample` field. Lastly, we've refactored the `invoke` command to make upcoming enhancements easier.\n\n**cli**\n\n* 🔨 Refactor `invoke` command ([#1217](https://github.com/zapier/zapier-platform/pull/1217))\n\n**core**\n\nNone!\n\n**schema**\n\n* 🎉 Allow a `sample` field to be provided for dynamic `outputFields` ([#1211](https://github.com/zapier/zapier-platform/pull/1211))\n\n**misc**\n\n* 🔨 Add publish job in CI ([#1212](https://github.com/zapier/zapier-platform/pull/1212), [#1223](https://github.com/zapier/zapier-platform/pull/1223))\n\n***\n\n## What's changed in v18.0.6\n\n*Released: 2025-12-24*\n\nThe `zapier build` command was harcoded to use `npm install`. As alternate package managers gain adoption, the `zapier build` command will respect your app's package manager of choice.\nIt does this by checking the `packageManager` on the package.json file. If it is not defined, it will look for any relevant lock files. If still, none is defined, then will fallback to `npm`.\n\nIf you are familiar with using `zapier build` with the flag `--skip-npm-install`, this flag has been renamed to `--skip-dep-install`, but will continue to still work as an alias. In the future, we will remove the `--skip-npm-install` flag.\n\n**cli**\n\n* 💅 CLI build respects the integration's package manager ([#1216](https://github.com/zapier/zapier-platform/pull/1216))\n\n**core**\n\nNone!\n\n**schema**\n\nNone!\n\n**misc**\n\n* 🔨 Bump tmp from 0.2.4 to 0.2.5 ([#1207](https://github.com/zapier/zapier-platform/pull/1207))\n* 🔨 Bump form-data from 4.0.4 to 4.0.5 ([#1208](https://github.com/zapier/zapier-platform/pull/1208))\n\n***\n\n## What's changed in v18.0.5\n\n*Released: 2025-12-10*\n\n<Info>\n We're releasing v18.0.5, skipping comprimised versions v18.0.2, v18.0.3, and\n v18.0.4, due to the prior [security\n incident](/integrations/news/2025/npm-package-sec-inc).\n</Info>\n\nThis release fixes a potential security vulnerability in the `build` command related to zip file decompression.\n\n**cli**\n\n* 🐛 Remove problematic decompress-tar dependency ([#1202](https://github.com/zapier/zapier-platform/pull/1202))\n\n**core**\n\nNone!\n\n**schema**\n\nNone!\n\n**misc**\n\n* 🔨 Switch to pnpm as package manager and task runner ([#1204](https://github.com/zapier/zapier-platform/pull/1204))\n\n***\n\n## Incident: Unauthorized Access to Zapier NPM Packages\n\n*Released: 2025-11-24*\n\n**Unauthorized Access to Zapier npm Packages**\n\n**Note: No action is needed from Zapier users**, only from Zapier developers using one of the NPM package versions listed [on this page](/integrations/build-cli/inc-547). See that link for detailed mitigation recommendations.\n\nAll Zapier products are operating as expected and there is no indication of data loss or leak.\n\nPlease [see this link](https://status.zapier.com/incidents/01KAV9DDHMYT7R6MFHSB8C09E3#updates) for the most up-to-date information.\n\n***\n\nLooking for older news? [2026](/integrations/news/2026), [2025](/integrations/news/2025), and [old changelogs prior to v17](https://github.com/zapier/zapier-platform/tree/main/changelog)\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://docs.zapier.com/integrations/news/single-page", "source_repo": "", "source_path": "", "section": "news", "tags": ["changelog", "news"], "related": [], "meta": {"year": null}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:babel", "kind": "template", "key": "babel", "title": "Source template: babel", "summary": "Full example-app source (n/a / example).", "body": "# example-app `babel`\n\nAuth: `n/a` · Pattern: `example`\n\n## `README.md`\n\n```md\n# \"Babel\" Example App For Zapier Platform\n\n[![Build Status](https://travis-ci.org/zapier/zapier-platform-example-app-babel.svg?branch=main)](https://travis-ci.org/zapier/zapier-platform-example-app-babel)\n\nA barebones app that has a resource defined. This is mainly a proof-of-concept for using features not yet available in node v12.x.\n\nRun this:\n\n```bash\nnpm run zapier-dev # compiles live\nzapier-platform test\n```\n\n`zapier-platform build` works as a non-watch command that calls the `npm run _zapier-build` hook, and `zapier-platform push` will make a fresh build using that hook as well.\n\n> We recommend using the zapier-platform-cli and `zapier-platform init .`  to create an app - youll be presented with a list of currently available templates to start with.\n\n```\n\n## `index.js`\n\n```js\nglobal._babelPolyfill || require('babel-polyfill');\n\nmodule.exports = require('./lib');\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"zapier-platform-example-app-babel\",\n \"version\": \"1.0.0\",\n \"description\": \"An example app for the Zapier platform.\",\n \"repository\": \"zapier/zapier-platform-example-app-babel\",\n \"homepage\": \"https://zapier.com/\",\n \"author\": \"Bryan Helmig <bryan@zapier.com>\",\n \"license\": \"BSD-3-Clause\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"zapier-build\": \"rm -rf lib && babel src --out-dir lib\",\n \"zapier-dev\": \"rm -rf lib && babel src --out-dir lib --watch\",\n \"prepare\": \"npm run zapier-build\",\n \"pretest\": \"npm run zapier-build\",\n \"test\": \"mocha --recursive lib/test --require babel-polyfill\",\n \"_zapier-build\": \"npm run zapier-build\"\n },\n \"engines\": {\n \"node\": \">=8.10.0\",\n \"npm\": \">=5.6.0\"\n },\n \"dependencies\": {\n \"babel-polyfill\": \"6.26.0\",\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"babel-cli\": \"6.26.0\",\n \"babel-core\": \"6.26.0\",\n \"babel-eslint\": \"8.2.3\",\n \"babel-plugin-add-module-exports\": \"0.2.1\",\n \"babel-plugin-transform-regenerator\": \"6.26.0\",\n \"babel-preset-env\": \"1.6.1\",\n \"mocha\": \"^5.2.0\",\n \"should\": \"^13.2.1\"\n },\n \"private\": true\n}\n\n```\n\n## `src/authentication.js`\n\n```js\nconst test = async (z /*, bundle */) => {\n // Normally you want to make a request to an endpoint that is either specifically designed to test auth, or one that\n // every user will have access to, such as an account or profile endpoint like /me.\n // In this example, we'll hit httpbin, which validates the Authorization Header against the arguments passed in the URL path\n const response = await z.request({\n url: 'https://auth-json-server.zapier-staging.com/me',\n });\n return response;\n};\n\nconst Authentication = {\n type: 'basic',\n\n // The test method allows Zapier to verify that the credentials a user provides are valid. We'll execute this\n // method whenever a user connects their account for the first time.\n test,\n // assuming \"username\" is a key returned from the test\n connectionLabel: '{{username}}',\n};\n\nexport default Authentication;\n\n```\n\n## `src/index.js`\n\n```js\nimport Authentication from './authentication';\nimport Recipe from './resources/recipe';\nimport { version } from '../package.json';\nimport { version as platformVersion } from 'zapier-platform-core';\n\nconst App = {\n version,\n platformVersion,\n\n authentication: Authentication,\n\n beforeRequest: [],\n\n afterResponse: [],\n\n resources: {\n [Recipe.key]: Recipe,\n },\n\n triggers: {},\n\n searches: {},\n\n creates: {},\n};\n\nexport default App;\n\n```\n\n## `src/resources/recipe.js`\n\n```js\nconst _sharedBaseUrl = 'https://auth-json-server.zapier-staging.com';\n\nconst getRecipe = async (z, bundle) => {\n const response = await z.request({\n url: `${_sharedBaseUrl}/recipes/${bundle.inputData.id}`,\n });\n return response.data;\n};\n\nconst listRecipes = async (z, bundle) => {\n const response = await z.request({\n url: _sharedBaseUrl + '/recipes',\n params: {\n style: bundle.inputData.style,\n },\n });\n return response.data;\n};\n\nconst createRecipe = async (z, bundle) => {\n const response = await z.request({\n url: _sharedBaseUrl + '/recipes',\n method: 'POST',\n body: {\n name: bundle.inputData.name,\n directions: bundle.inputData.directions,\n authorId: bundle.inputData.authorId,\n },\n headers: {\n 'content-type': 'application/json',\n },\n });\n return response.data;\n};\n\nconst searchRecipe = async (z, bundle) => {\n const response = await z.request({\n url: _sharedBaseUrl + '/recipes',\n params: {\n nameSearch: bundle.inputData.name,\n },\n });\n const matchingRecipes = response.data;\n\n // Only return the first matching recipe\n if (matchingRecipes && matchingRecipes.length) {\n return matchingRecipes[0];\n }\n\n return [];\n};\n\nconst sample = {\n id: 1,\n createdAt: 1472069465,\n name: 'Best Spagetti Ever',\n authorId: 1,\n directions: '1. Boil Noodles\\n2.Serve with sauce',\n style: 'italian',\n};\n\n// This file exports a Recipe resource. The definition below contains all of the keys available,\n// and implements the list and create methods.\nconst Recipe = {\n key: 'recipe',\n noun: 'Recipe',\n // The get method is used by Zapier to fetch a complete representation of a record. This is helpful when the HTTP\n // response from a create call only return an ID, or a search that only returns a minimuml representation of the\n // record. Zapier will follow these up with the get() to retrieve the entire object.\n get: {\n display: {\n label: 'Get Recipe',\n description: 'Gets a recipe.',\n },\n operation: {\n inputFields: [{ key: 'id', required: true }],\n perform: getRecipe,\n sample,\n },\n },\n // The list method on this resource becomes a Trigger on the app. Zapier will use polling to watch for new records\n list: {\n display: {\n label: 'New Recipe',\n description: 'Trigger when a new recipe is added.',\n },\n operation: {\n inputFields: [\n {\n key: 'style',\n type: 'string',\n helpText: 'Explain what style of cuisine this is.',\n },\n ],\n perform: listRecipes,\n sample,\n },\n },\n // If your app supports webhooks, you can define a hook method instead of a list method.\n // Zapier will turn this into a webhook Trigger on the app.\n // hook: {\n //\n // },\n\n create: {\n display: {\n label: 'Create Recipe',\n description: 'Creates a new recipe.',\n },\n operation: {\n inputFields: [\n { key: 'name', required: true, type: 'string' },\n {\n key: 'directions',\n required: true,\n type: 'text',\n helpText: 'Explain how should one make the recipe, step by step.',\n },\n {\n key: 'authorId',\n required: true,\n type: 'integer',\n label: 'Author ID',\n },\n {\n key: 'style',\n required: false,\n type: 'string',\n helpText: 'Explain what style of cuisine this is.',\n },\n ],\n perform: createRecipe,\n sample,\n },\n },\n\n search: {\n display: {\n label: 'Find Recipe',\n description: 'Finds an existing recipe by name.',\n },\n operation: {\n inputFields: [{ key: 'name', required: true, type: 'string' }],\n perform: searchRecipe,\n sample,\n },\n },\n\n // In cases where Zapier needs to show an example record to the user, but we are unable to get a live example\n // from the API, Zapier will fallback to this hard-coded sample. It should reflect the data structure of\n // returned records, and have obviously dummy values that we can show to any user.\n sample,\n\n // If the resource can have fields that are custom on a per-user basis, define a function to fetch the custom\n // field definitions. The result will be used to augment the sample.\n // outputFields: () => { return []; }\n // Alternatively, a static field definition should be provided, to specify labels for the fields\n outputFields: [\n { key: 'id', label: 'ID' },\n { key: 'createdAt', label: 'Created At' },\n { key: 'name', label: 'Name' },\n { key: 'directions', label: 'Directions' },\n { key: 'authorId', label: 'Author ID' },\n { key: 'style', label: 'Style' },\n ],\n};\n\nexport default Recipe;\n\n```\n\n## `src/test/index.js`\n\n```js\n/* globals describe, it */\nimport should from 'should';\n\nimport zapier from 'zapier-platform-core';\n\nimport App from '../index';\nconst appTester = zapier.createAppTester(App);\n\ndescribe('My Test', () => {\n it('should test the auth succeeds', async () => {\n const bundle = {\n authData: {\n username: 'user',\n password: 'secret',\n },\n };\n\n const response = await appTester(App.authentication.test, bundle);\n should(response.status).eql(200);\n response.request.headers.Authorization.should.eql('Basic dXNlcjpzZWNyZXQ=');\n });\n\n it('should test the auth fails', () => {\n const bundle = {\n authData: {\n username: 'user',\n password: 'boom',\n },\n };\n\n return appTester(App.authentication.test, bundle).should.be.rejected();\n });\n});\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/babel", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/babel", "section": "templates", "tags": ["example", "template"], "related": [], "meta": {"files": ["index.js", "README.md", "package.json", "src/index.js", "src/authentication.js", "src/test/index.js", "src/resources/recipe.js"], "auth": null, "pattern": "example", "local": "repos/zapier-platform/example-apps/babel"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:basic-auth", "kind": "template", "key": "basic-auth", "title": "Source template: basic-auth", "summary": "Full example-app source (basic-auth / example).", "body": "# example-app `basic-auth`\n\nAuth: `basic-auth` · Pattern: `example`\n\n## `README.md`\n\n```md\n# basic-auth\n\nThis Zapier integration project is generated by the `zapier-platform init` CLI command.\n\nThese are what you normally do next:\n\n```bash\n# Install dependencies\nnpm install # or you can use yarn\n\n# Run tests\nzapier-platform test\n\n# Register the integration on Zapier if you haven't\nzapier-platform register \"App Title\"\n\n# Or you can link to an existing integration on Zapier\nzapier-platform link\n\n# Push it to Zapier\nzapier-platform push\n```\n\nThen, to add more features, you can use the `zapier-platform scaffold` command, for example:\n\n```bash\n# Add a trigger\nzapier-platform scaffold trigger contact\n\n# Add an action\nzapier-platform scaffold create contact\n``` \n\nFind out more on the latest docs: https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md.\n\n```\n\n## `authentication.js`\n\n```js\n'use strict';\n\n// You want to make a request to an endpoint that is either specifically designed\n// to test auth, or one that every user will have access to. eg: `/me`.\n// By returning the entire request object, you have access to the request and\n// response data for testing purposes. Your connection label can access any data\n// from the returned response using the `json.` prefix. eg: `{{json.username}}`.\nconst test = (z, bundle) =>\n z.request({ url: 'https://auth-json-server.zapier-staging.com/me' });\n\nmodule.exports = {\n // \"basic\" auth automatically creates \"username\" and \"password\" input fields. It\n // also registers default middleware to create the authentication header.\n type: 'basic',\n\n // Define any input app's auth requires here. The user will be prompted to enter\n // this info when they connect their account.\n fields: [],\n\n // The test method allows Zapier to verify that the credentials a user provides\n // are valid. We'll execute this method whenever a user connects their account for\n // the first time.\n test,\n\n // This template string can access all the data returned from the auth test. If\n // you return the test object, you'll access the returned data with a label like\n // `{{json.X}}`. If you return `response.data` from your test, then your label can\n // be `{{X}}`. This can also be a function that returns a label. That function has\n // the standard args `(z, bundle)` and data returned from the test can be accessed\n // in `bundle.inputData.X`.\n connectionLabel: '{{json.username}}',\n};\n\n```\n\n## `index.js`\n\n```js\nconst authentication = require('./authentication');\nconst { befores = [], afters = [] } = require('./middleware');\n\nmodule.exports = {\n // This is just shorthand to reference the installed dependencies you have.\n // Zapier will need to know these before we can upload.\n version: require('./package.json').version,\n platformVersion: require('zapier-platform-core').version,\n\n authentication,\n\n beforeRequest: [...befores],\n\n afterResponse: [...afters],\n\n // If you want your trigger to show up, you better include it here!\n triggers: {},\n\n // If you want your searches to show up, you better include it here!\n searches: {},\n\n // If you want your creates to show up, you better include it here!\n creates: {},\n\n resources: {},\n};\n\n```\n\n## `middleware.js`\n\n```js\n'use strict';\n\n// This function runs after every outbound request. You can use it to check for\n// errors or modify the response. You can have as many as you need. They'll need\n// to each be registered in your index.js file.\nconst handleBadResponses = (response, z, bundle) => {\n if (response.status === 401) {\n throw new z.errors.Error(\n // This message is surfaced to the user\n 'The username and/or password you supplied is incorrect',\n 'AuthenticationError',\n response.status,\n );\n }\n\n return response;\n};\n\nmodule.exports = { befores: [], afters: [handleBadResponses] };\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"basic-auth\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"jest --testTimeout 10000\"\n },\n \"dependencies\": {\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"jest\": \"^29.6.0\"\n },\n \"private\": true\n}\n\n```\n\n## `test/authentication.test.js`\n\n```js\n/* globals describe, it, expect */\n\nconst zapier = require('zapier-platform-core');\n\nconst App = require('../index');\nconst appTester = zapier.createAppTester(App);\n\ndescribe('basic auth', () => {\n it('automatically has Authorize Header add', async () => {\n const bundle = {\n authData: {\n username: 'user',\n password: 'secret',\n },\n };\n\n const response = await appTester(App.authentication.test, bundle);\n\n expect(response.status).toBe(200);\n expect(response.request.headers.Authorization).toBe(\n 'Basic dXNlcjpzZWNyZXQ=',\n );\n });\n\n it('fails on bad auth', async () => {\n const bundle = {\n authData: {\n username: 'user',\n password: 'badpwd',\n },\n };\n\n try {\n await appTester(App.authentication.test, bundle);\n } catch (err) {\n expect(err.message).toContain(\n 'The username and/or password you supplied is incorrect',\n );\n return;\n }\n throw new Error('appTester should have thrown');\n });\n});\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/basic-auth", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/basic-auth", "section": "templates", "tags": ["basic-auth", "example", "template"], "related": ["zapier-platform init --template basic-auth"], "meta": {"files": ["index.js", "README.md", "package.json", "middleware.js", "authentication.js", "test/authentication.test.js"], "auth": "basic-auth", "pattern": "example", "local": "repos/zapier-platform/example-apps/basic-auth"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:basic-auth-typescript", "kind": "template", "key": "basic-auth-typescript", "title": "Source template: basic-auth-typescript", "summary": "Full example-app source (basic-auth / example).", "body": "# example-app `basic-auth-typescript`\n\nAuth: `basic-auth` · Pattern: `example`\n\n## `README.md`\n\n```md\n# basic-auth-typescript\n\nThis Zapier integration project is generated by the `zapier-platform init` CLI command.\n\nThese are what you normally do next:\n\n```bash\n# Install dependencies\nnpm install # or you can use yarn\n\n# Run tests\nzapier-platform test\n\n# Register the integration on Zapier if you haven't\nzapier-platform register \"App Title\"\n\n# Or you can link to an existing integration on Zapier\nzapier-platform link\n\n# Push it to Zapier\nzapier-platform push\n```\n\nThen, to add more features, you can use the `zapier-platform scaffold` command, for example:\n\n```bash\n# Add a trigger\nzapier-platform scaffold trigger contact\n\n# Add an action\nzapier-platform scaffold create contact\n``` \n\nFind out more on the latest docs: https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md.\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"basic-auth-typescript\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"scripts\": {\n \"test\": \"npm run build && vitest --run\",\n \"clean\": \"rimraf ./dist ./build\",\n \"build\": \"npm run clean && tsc\",\n \"_zapier-build\": \"npm run build\"\n },\n \"dependencies\": {\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"rimraf\": \"^5.0.10\",\n \"typescript\": \"5.6.2\",\n \"vitest\": \"^2.1.2\"\n },\n \"private\": true,\n \"exports\": \"./dist/index.js\",\n \"type\": \"module\"\n}\n\n```\n\n## `src/authentication.ts`\n\n```ts\nimport type { ZObject, Bundle, Authentication } from 'zapier-platform-core';\n\n// You want to make a request to an endpoint that is either specifically designed\n// to test auth, or one that every user will have access to. eg: `/me`.\n// By returning the entire request object, you have access to the request and\n// response data for testing purposes. Your connection label can access any data\n// from the returned response using the `json.` prefix. eg: `{{json.username}}`.\nconst test = (z: ZObject, bundle: Bundle) =>\n z.request({ url: 'https://auth-json-server.zapier-staging.com/me' });\n\nexport default {\n // \"basic\" auth automatically creates \"username\" and \"password\" input fields. It\n // also registers default middleware to create the authentication header.\n type: 'basic',\n\n // Define any input app's auth requires here. The user will be prompted to enter\n // this info when they connect their account.\n fields: [],\n\n // The test method allows Zapier to verify that the credentials a user provides\n // are valid. We'll execute this method whenever a user connects their account for\n // the first time.\n test,\n\n // This template string can access all the data returned from the auth test. If\n // you return the test object, you'll access the returned data with a label like\n // `{{json.X}}`. If you return `response.data` from your test, then your label can\n // be `{{X}}`. This can also be a function that returns a label. That function has\n // the standard args `(z: ZObject, bundle: Bundle)` and data returned from the\n // test can be accessed in `bundle.inputData.X`.\n connectionLabel: '{{json.username}}',\n} satisfies Authentication;\n\n```\n\n## `src/index.ts`\n\n```ts\nimport zapier, { defineApp } from 'zapier-platform-core';\n\nimport packageJson from '../package.json' with { type: 'json' };\n\nimport authentication from './authentication.js';\nimport { befores, afters } from './middleware.js';\n\nexport default defineApp({\n version: packageJson.version,\n platformVersion: zapier.version,\n\n authentication,\n beforeRequest: [...befores],\n afterResponse: [...afters],\n\n // Add your triggers here for them to show up!\n triggers: {},\n\n // Add your creates here for them to show up!\n creates: {},\n});\n\n```\n\n## `src/middleware.ts`\n\n```ts\nimport type { ZObject, Bundle, Authentication } from 'zapier-platform-core';\n\n// This function runs after every outbound request. You can use it to check for\n// errors or modify the response. You can have as many as you need. They'll need\n// to each be registered in your index.js file.\nconst handleBadResponses = (response, z: ZObject, bundle: Bundle) => {\n if (response.status === 401) {\n throw new z.errors.Error(\n // This message is surfaced to the user\n 'The username and/or password you supplied is incorrect',\n 'AuthenticationError',\n response.status,\n );\n }\n\n return response;\n};\n\nexport const befores = [];\n\nexport const afters = [handleBadResponses];\n\n```\n\n## `src/test/authentication.test.ts`\n\n```ts\nimport { describe, expect, it } from 'vitest';\nimport zapier from 'zapier-platform-core';\n\nimport App from '../index.js';\nconst appTester = zapier.createAppTester(App);\n\ndescribe('basic auth', () => {\n it('automatically has Authorize Header add', async () => {\n const bundle = {\n authData: {\n username: 'user',\n password: 'secret',\n },\n };\n\n const response = await appTester(App.authentication.test, bundle);\n\n expect(response.status).toBe(200);\n expect(response.request.headers.Authorization).toBe(\n 'Basic dXNlcjpzZWNyZXQ=',\n );\n });\n\n it('fails on bad auth', async () => {\n const bundle = {\n authData: {\n username: 'user',\n password: 'badpwd',\n },\n };\n\n try {\n await appTester(App.authentication.test, bundle);\n } catch (err) {\n expect(err.message).toContain(\n 'The username and/or password you supplied is incorrect',\n );\n return;\n }\n throw new Error('appTester should have thrown');\n });\n});\n\n```\n\n## `tsconfig.json`\n\n```json\n{\n \"compilerOptions\": {\n \"target\": \"ESNext\",\n \"module\": \"NodeNext\",\n \"moduleResolution\": \"NodeNext\",\n \"resolveJsonModule\": true,\n \"esModuleInterop\": true,\n \"noUncheckedIndexedAccess\": true,\n \"isolatedModules\": true,\n \"noImplicitAny\": false,\n \"skipLibCheck\": true,\n \"outDir\": \"./dist\",\n \"rootDir\": \"./src\",\n \"strict\": true\n },\n \"include\": [\"./src/**/*.ts\"],\n \"exclude\": [\"./**/*.test.ts\"]\n}\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/basic-auth-typescript", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/basic-auth-typescript", "section": "templates", "tags": ["basic-auth", "example", "template"], "related": ["zapier-platform init --template basic-auth-typescript"], "meta": {"files": ["README.md", "package.json", "tsconfig.json", "src/middleware.ts", "src/authentication.ts", "src/index.ts", "src/test/authentication.test.ts"], "auth": "basic-auth", "pattern": "example", "local": "repos/zapier-platform/example-apps/basic-auth-typescript"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:callback", "kind": "template", "key": "callback", "title": "Source template: callback", "summary": "Full example-app source (n/a / callback).", "body": "# example-app `callback`\n\nAuth: `n/a` · Pattern: `callback`\n\n## `README.md`\n\n```md\n# callback\n\nThis Zapier integration project is generated by the `zapier-platform init` CLI command.\n\nThese are what you normally do next:\n\n```bash\n# Install dependencies\nnpm install # or you can use yarn\n\n# Run tests\nzapier-platform test\n\n# Register the integration on Zapier if you haven't\nzapier-platform register \"App Title\"\n\n# Or you can link to an existing integration on Zapier\nzapier-platform link\n\n# Push it to Zapier\nzapier-platform push\n```\n\nFind out more on the latest docs: https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md.\n\n# The \"Callback\" Template\n\nThis example has a create showcasing the `performResume` callback function.\n\nFind out more in the docs: https://github.com/zapier/zapier-platform/blob/main/packages/cli#zgeneratecallbackurl.\n\n```\n\n## `creates/prediction.js`\n\n```js\n// We recommend writing your creates separate like this and rolling them\n// into the App definition at the end.\nmodule.exports = {\n key: 'prediction',\n\n // You'll want to provide some helpful display labels and descriptions\n // for users. Zapier will put them into the UX.\n noun: 'Prediction',\n display: {\n label: 'Create Prediction',\n description: 'Creates a new prediction.',\n },\n\n // `operation` is where the business logic goes.\n operation: {\n inputFields: [\n {\n key: 'question',\n required: true,\n type: 'string',\n helpText: 'Provide a \"Yes\" or \"No\" question to ask the Magic 8-Ball.',\n },\n ],\n perform: (z, bundle) => {\n const promise = z.request({\n url: 'https://auth-json-server.zapier-staging.com/magic',\n method: 'POST',\n body: {\n callbackUrl: z.generateCallbackUrl(),\n },\n headers: {\n 'content-type': 'application/json',\n\n // This is NOT how you normally do authentication. This is just to demo how to write a create here.\n // Refer to this doc to set up authentication:\n // https://docs.zapier.com/platform/reference/cli-docs#authentication\n 'X-API-Key': 'secret',\n },\n });\n\n return promise.then((response) => ({ ...response.data, extra: 'data' }));\n },\n\n performResume: (z, bundle) => {\n // The original output from perform is available in bundle.outputData.\n // The data POSTed to the callbackUrl is in bundle.cleanedRequest.\n // The full request object corresponding to bundle.cleanedRequest can be found in bundle.rawRequest.\n const { extra, ...originalOutput } = bundle.outputData;\n // The following line will return an object containing the contents of the original API response to the\n // request from the perform function merged with the contents of the new request from the API.\n return { ...originalOutput, ...bundle.cleanedRequest };\n },\n\n // In cases where Zapier needs to show an example record to the user, but we are unable to get a live example\n // from the API, Zapier will fallback to this hard-coded sample. It should reflect the data structure of\n // returned records, and have obviously dummy values that we can show to any user.\n sample: {\n callbackUrl: 'http://zapier.com/hooks/catch/-1234/abcdef/',\n status: 'success',\n result: 'Ask again later.',\n },\n\n // If the resource can have fields that are custom on a per-user basis, define a function to fetch the custom\n // field definitions. The result will be used to augment the sample.\n // outputFields: () => { return []; }\n // Alternatively, a static field definition should be provided, to specify labels for the fields\n outputFields: [\n { key: 'callbackUrl', label: 'Callback URL' },\n { key: 'status', label: 'Status' },\n { key: 'result', label: 'Predicted Result' },\n ],\n },\n};\n\n```\n\n## `index.js`\n\n```js\nconst prediction = require('./creates/prediction');\n\n// Now we can roll up all our behaviors in an App.\nconst App = {\n // This is just shorthand to reference the installed dependencies you have. Zapier will\n // need to know these before we can upload\n version: require('./package.json').version,\n platformVersion: require('zapier-platform-core').version,\n\n // If you want your creates to show up, you better include it here!\n creates: {\n [prediction.key]: prediction,\n },\n};\n\n// Finally, export the app.\nmodule.exports = App;\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"callback\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"jest --testTimeout 10000\"\n },\n \"dependencies\": {\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"jest\": \"^25.5.3\"\n },\n \"private\": true\n}\n\n```\n\n## `test/creates.test.js`\n\n```js\n/* globals describe, expect, test */\n\nconst zapier = require('zapier-platform-core');\n\nconst App = require('../index');\nconst appTester = zapier.createAppTester(App);\nzapier.tools.env.inject();\n\ndescribe('creates', () => {\n test('perform function returns intermediate data', async () => {\n const bundle = { inputData: { question: 'Will this work?' } };\n const result = await appTester(\n App.creates.prediction.operation.perform,\n bundle,\n );\n expect(result).toMatchObject({\n status: '...thinking...',\n callbackUrl: 'https://auth-json-server.zapier-staging.com/echo',\n extra: 'data',\n });\n });\n\n test('performResume function returns \"final\" data', async () => {\n const bundle = {\n outputData: {\n callbackUrl: 'https://auth-json-server.zapier-staging.com/echo',\n status: '...thinking...',\n extra: 'data',\n },\n cleanedRequest: {\n status: 'success',\n result: 'Ask again later.',\n },\n };\n\n const result = await appTester(\n App.creates.prediction.operation.performResume,\n bundle,\n );\n expect(result).toMatchObject({\n status: 'success',\n result: 'Ask again later.',\n callbackUrl: 'https://auth-json-server.zapier-staging.com/echo',\n });\n });\n});\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/callback", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/callback", "section": "templates", "tags": ["callback", "example", "template"], "related": ["zapier-platform init --template callback"], "meta": {"files": ["index.js", "README.md", "package.json", "creates/prediction.js", "test/creates.test.js"], "auth": null, "pattern": "callback", "local": "repos/zapier-platform/example-apps/callback"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:create", "kind": "template", "key": "create", "title": "Source template: create", "summary": "Full example-app source (n/a / create).", "body": "# example-app `create`\n\nAuth: `n/a` · Pattern: `create`\n\n## `README.md`\n\n```md\n# \"Create\" Example App For Zapier Platform\n\n[![Build Status](https://travis-ci.org/zapier/zapier-platform-example-app-create.svg?branch=main)](https://travis-ci.org/zapier/zapier-platform-example-app-create)\n\nA barebones app that has a create defined.\n\n> We recommend using the zapier-platform-cli and `zapier-platform init .`  to create an app - youll be presented with a list of currently available templates to start with.\n\n```\n\n## `creates/recipe.js`\n\n```js\n// We recommend writing your creates separate like this and rolling them\n// into the App definition at the end.\nmodule.exports = {\n key: 'recipe',\n\n // You'll want to provide some helpful display labels and descriptions\n // for users. Zapier will put them into the UX.\n noun: 'Recipe',\n display: {\n label: 'Create Recipe',\n description: 'Creates a new recipe.',\n },\n\n // `operation` is where the business logic goes.\n operation: {\n inputFields: [\n { key: 'name', required: true, type: 'string' },\n {\n key: 'directions',\n required: true,\n type: 'text',\n helpText: 'Explain how should one make the recipe, step by step.',\n },\n { key: 'authorId', required: true, type: 'integer', label: 'Author ID' },\n {\n key: 'style',\n required: false,\n type: 'string',\n helpText: 'Explain what style of cuisine this is.',\n },\n ],\n perform: (z, bundle) => {\n const promise = z.request({\n url: 'https://auth-json-server.zapier-staging.com/recipes',\n method: 'POST',\n body: {\n name: bundle.inputData.name,\n directions: bundle.inputData.directions,\n authorId: bundle.inputData.authorId,\n style: bundle.inputData.style,\n },\n headers: {\n 'content-type': 'application/json',\n\n // This is NOT how you normally do authentication. This is just to demo how to write a create here.\n // Refer to this doc to set up authentication:\n // https://docs.zapier.com/platform/reference/cli-docs#authentication\n 'X-API-Key': 'secret',\n },\n });\n\n return promise.then((response) => response.data);\n },\n\n // In cases where Zapier needs to show an example record to the user, but we are unable to get a live example\n // from the API, Zapier will fallback to this hard-coded sample. It should reflect the data structure of\n // returned records, and have obviously dummy values that we can show to any user.\n sample: {\n id: 1,\n createdAt: 1472069465,\n name: 'Best Spagetti Ever',\n authorId: 1,\n directions: '1. Boil Noodles\\n2.Serve with sauce',\n style: 'italian',\n },\n\n // If the resource can have fields that are custom on a per-user basis, define a function to fetch the custom\n // field definitions. The result will be used to augment the sample.\n // outputFields: () => { return []; }\n // Alternatively, a static field definition should be provided, to specify labels for the fields\n outputFields: [\n { key: 'id', label: 'ID' },\n { key: 'createdAt', label: 'Created At' },\n { key: 'name', label: 'Name' },\n { key: 'directions', label: 'Directions' },\n { key: 'authorId', label: 'Author ID' },\n { key: 'style', label: 'Style' },\n ],\n },\n};\n\n```\n\n## `index.js`\n\n```js\nconst recipe = require('./creates/recipe');\n\n// Now we can roll up all our behaviors in an App.\nconst App = {\n // This is just shorthand to reference the installed dependencies you have. Zapier will\n // need to know these before we can upload\n version: require('./package.json').version,\n platformVersion: require('zapier-platform-core').version,\n\n beforeRequest: [],\n\n afterResponse: [],\n\n resources: {},\n\n // If you want your trigger to show up, you better include it here!\n triggers: {},\n\n // If you want your searches to show up, you better include it here!\n searches: {},\n\n // If you want your creates to show up, you better include it here!\n creates: {\n [recipe.key]: recipe,\n },\n};\n\n// Finally, export the app.\nmodule.exports = App;\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"zapier-platform-example-app-create\",\n \"version\": \"1.0.0\",\n \"description\": \"An example app for the Zapier platform.\",\n \"repository\": \"zapier/zapier-platform-example-app-create\",\n \"homepage\": \"https://zapier.com/\",\n \"author\": \"Bryan Helmig <bryan@zapier.com>\",\n \"license\": \"BSD-3-Clause\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"mocha --recursive\"\n },\n \"engines\": {\n \"node\": \">=8.10.0\",\n \"npm\": \">=5.6.0\"\n },\n \"dependencies\": {\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"mocha\": \"^5.2.0\",\n \"should\": \"^13.2.0\"\n },\n \"private\": true\n}\n\n```\n\n## `test/creates.js`\n\n```js\n/* globals describe, it */\n\nrequire('should');\n\nconst zapier = require('zapier-platform-core');\n\nconst App = require('../index');\nconst appTester = zapier.createAppTester(App);\n\ndescribe('creates', () => {\n describe('create recipe create', () => {\n it('should create a new recipe', (done) => {\n const bundle = {\n inputData: {\n name: 'Smith Family Recipe',\n directions: '1. Order out :)',\n authorId: 1,\n },\n };\n\n appTester(App.creates.recipe.operation.perform, bundle)\n .then((result) => {\n result.should.have.property('name');\n done();\n })\n .catch(done);\n });\n });\n});\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/create", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/create", "section": "templates", "tags": ["create", "example", "template"], "related": [], "meta": {"files": ["index.js", "README.md", "package.json", "creates/recipe.js", "test/creates.js"], "auth": null, "pattern": "create", "local": "repos/zapier-platform/example-apps/create"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:custom-auth", "kind": "template", "key": "custom-auth", "title": "Source template: custom-auth", "summary": "Full example-app source (custom-auth / example).", "body": "# example-app `custom-auth`\n\nAuth: `custom-auth` · Pattern: `example`\n\n## `README.md`\n\n```md\n# custom-auth\n\nThis Zapier integration project is generated by the `zapier-platform init` CLI command.\n\nThese are what you normally do next:\n\n```bash\n# Install dependencies\nnpm install # or you can use yarn\n\n# Run tests\nzapier-platform test\n\n# Register the integration on Zapier if you haven't\nzapier-platform register \"App Title\"\n\n# Or you can link to an existing integration on Zapier\nzapier-platform link\n\n# Push it to Zapier\nzapier-platform push\n```\n\nThen, to add more features, you can use the `zapier-platform scaffold` command, for example:\n\n```bash\n# Add a trigger\nzapier-platform scaffold trigger contact\n\n# Add an action\nzapier-platform scaffold create contact\n``` \n\nFind out more on the latest docs: https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md.\n\n```\n\n## `authentication.js`\n\n```js\n'use strict';\n\n// You want to make a request to an endpoint that is either specifically designed\n// to test auth, or one that every user will have access to. eg: `/me`.\n// By returning the entire request object, you have access to the request and\n// response data for testing purposes. Your connection label can access any data\n// from the returned response using the `json.` prefix. eg: `{{json.username}}`.\nconst test = (z, bundle) =>\n z.request({ url: 'https://auth-json-server.zapier-staging.com/me' });\n\nmodule.exports = {\n // \"custom\" is the catch-all auth type. The user supplies some info and Zapier can\n // make authenticated requests with it\n type: 'custom',\n\n // Define any input app's auth requires here. The user will be prompted to enter\n // this info when they connect their account.\n fields: [{ key: 'apiKey', label: 'API Key', required: true }],\n\n // The test method allows Zapier to verify that the credentials a user provides\n // are valid. We'll execute this method whenever a user connects their account for\n // the first time.\n test,\n\n // This template string can access all the data returned from the auth test. If\n // you return the test object, you'll access the returned data with a label like\n // `{{json.X}}`. If you return `response.data` from your test, then your label can\n // be `{{X}}`. This can also be a function that returns a label. That function has\n // the standard args `(z, bundle)` and data returned from the test can be accessed\n // in `bundle.inputData.X`.\n connectionLabel: '{{json.username}}',\n};\n\n```\n\n## `index.js`\n\n```js\nconst authentication = require('./authentication');\nconst { befores = [], afters = [] } = require('./middleware');\n\nmodule.exports = {\n // This is just shorthand to reference the installed dependencies you have.\n // Zapier will need to know these before we can upload.\n version: require('./package.json').version,\n platformVersion: require('zapier-platform-core').version,\n\n authentication,\n\n beforeRequest: [...befores],\n\n afterResponse: [...afters],\n\n // If you want your trigger to show up, you better include it here!\n triggers: {},\n\n // If you want your searches to show up, you better include it here!\n searches: {},\n\n // If you want your creates to show up, you better include it here!\n creates: {},\n\n resources: {},\n};\n\n```\n\n## `middleware.js`\n\n```js\n'use strict';\n\n// This function runs after every outbound request. You can use it to check for\n// errors or modify the response. You can have as many as you need. They'll need\n// to each be registered in your index.js file.\nconst handleBadResponses = (response, z, bundle) => {\n if (response.status === 401) {\n throw new z.errors.Error(\n // This message is surfaced to the user\n 'The API Key you supplied is incorrect',\n 'AuthenticationError',\n response.status,\n );\n }\n\n return response;\n};\n\n// This function runs before every outbound request. You can have as many as you\n// need. They'll need to each be registered in your index.js file.\nconst includeApiKey = (request, z, bundle) => {\n if (bundle.authData.apiKey) {\n // Use these lines to include the API key in the querystring\n request.params = request.params || {};\n request.params.api_key = bundle.authData.apiKey;\n\n // If you want to include the API key in the header instead, uncomment this:\n // request.headers.Authorization = bundle.authData.apiKey;\n }\n\n return request;\n};\n\nmodule.exports = { befores: [includeApiKey], afters: [handleBadResponses] };\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"custom-auth\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"jest --testTimeout 10000\"\n },\n \"dependencies\": {\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"jest\": \"^29.6.0\"\n },\n \"private\": true\n}\n\n```\n\n## `test/authentication.test.js`\n\n```js\n/* globals describe, it, expect */\n\nconst zapier = require('zapier-platform-core');\n\nconst App = require('../index');\nconst appTester = zapier.createAppTester(App);\n\ndescribe('custom auth', () => {\n it('passes authentication and returns json', async () => {\n const bundle = {\n authData: {\n apiKey: 'secret',\n },\n };\n\n const response = await appTester(App.authentication.test, bundle);\n expect(response.data).toHaveProperty('username');\n });\n\n it('fails on bad auth', async () => {\n const bundle = {\n authData: {\n apiKey: 'bad',\n },\n };\n\n try {\n await appTester(App.authentication.test, bundle);\n } catch (error) {\n expect(error.message).toContain('The API Key you supplied is incorrect');\n return;\n }\n throw new Error('appTester should have thrown');\n });\n});\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/custom-auth", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/custom-auth", "section": "templates", "tags": ["custom-auth", "example", "template"], "related": ["zapier-platform init --template custom-auth"], "meta": {"files": ["index.js", "README.md", "package.json", "middleware.js", "authentication.js", "test/authentication.test.js"], "auth": "custom-auth", "pattern": "example", "local": "repos/zapier-platform/example-apps/custom-auth"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:custom-auth-typescript", "kind": "template", "key": "custom-auth-typescript", "title": "Source template: custom-auth-typescript", "summary": "Full example-app source (custom-auth / example).", "body": "# example-app `custom-auth-typescript`\n\nAuth: `custom-auth` · Pattern: `example`\n\n## `README.md`\n\n```md\n# custom-auth-typescript\n\nThis Zapier integration project is generated by the `zapier-platform init` CLI command.\n\nThese are what you normally do next:\n\n```bash\n# Install dependencies\nnpm install # or you can use yarn\n\n# Run tests\nzapier-platform test\n\n# Register the integration on Zapier if you haven't\nzapier-platform register \"App Title\"\n\n# Or you can link to an existing integration on Zapier\nzapier-platform link\n\n# Push it to Zapier\nzapier-platform push\n```\n\nThen, to add more features, you can use the `zapier-platform scaffold` command, for example:\n\n```bash\n# Add a trigger\nzapier-platform scaffold trigger contact\n\n# Add an action\nzapier-platform scaffold create contact\n``` \n\nFind out more on the latest docs: https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md.\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"custom-auth-typescript\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"scripts\": {\n \"test\": \"npm run build && vitest --run\",\n \"clean\": \"rimraf ./dist ./build\",\n \"build\": \"npm run clean && tsc\",\n \"_zapier-build\": \"npm run build\"\n },\n \"dependencies\": {\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"rimraf\": \"^5.0.10\",\n \"typescript\": \"5.6.2\",\n \"vitest\": \"^2.1.2\"\n },\n \"private\": true,\n \"exports\": \"./dist/index.js\",\n \"type\": \"module\"\n}\n\n```\n\n## `src/authentication.ts`\n\n```ts\nimport type { ZObject, Bundle, Authentication } from 'zapier-platform-core';\n\n// You want to make a request to an endpoint that is either specifically designed\n// to test auth, or one that every user will have access to. eg: `/me`.\n// By returning the entire request object, you have access to the request and\n// response data for testing purposes. Your connection label can access any data\n// from the returned response using the `json.` prefix. eg: `{{json.username}}`.\nconst test = (z: ZObject, bundle: Bundle) =>\n z.request({ url: 'https://auth-json-server.zapier-staging.com/me' });\n\nexport default {\n // \"custom\" is the catch-all auth type. The user supplies some info and Zapier can\n // make authenticated requests with it\n type: 'custom',\n\n // Define any input app's auth requires here. The user will be prompted to enter\n // this info when they connect their account.\n fields: [{ key: 'apiKey', label: 'API Key', required: true }],\n\n // The test method allows Zapier to verify that the credentials a user provides\n // are valid. We'll execute this method whenever a user connects their account for\n // the first time.\n test,\n\n // This template string can access all the data returned from the auth test. If\n // you return the test object, you'll access the returned data with a label like\n // `{{json.X}}`. If you return `response.data` from your test, then your label can\n // be `{{X}}`. This can also be a function that returns a label. That function has\n // the standard args `(z: ZObject, bundle: Bundle)` and data returned from the\n // test can be accessed in `bundle.inputData.X`.\n connectionLabel: '{{json.username}}',\n} satisfies Authentication;\n\n```\n\n## `src/index.ts`\n\n```ts\nimport zapier, { defineApp } from 'zapier-platform-core';\n\nimport packageJson from '../package.json' with { type: 'json' };\n\nimport authentication from './authentication.js';\nimport { befores, afters } from './middleware.js';\n\nexport default defineApp({\n version: packageJson.version,\n platformVersion: zapier.version,\n\n authentication,\n beforeRequest: [...befores],\n afterResponse: [...afters],\n\n // Add your triggers here for them to show up!\n triggers: {},\n\n // Add your creates here for them to show up!\n creates: {},\n});\n\n```\n\n## `src/middleware.ts`\n\n```ts\nimport type { ZObject, Bundle, Authentication } from 'zapier-platform-core';\n\n// This function runs after every outbound request. You can use it to check for\n// errors or modify the response. You can have as many as you need. They'll need\n// to each be registered in your index.js file.\nconst handleBadResponses = (response, z: ZObject, bundle: Bundle) => {\n if (response.status === 401) {\n throw new z.errors.Error(\n // This message is surfaced to the user\n 'The API Key you supplied is incorrect',\n 'AuthenticationError',\n response.status,\n );\n }\n\n return response;\n};\n\n// This function runs before every outbound request. You can have as many as you\n// need. They'll need to each be registered in your index.js file.\nconst includeApiKey = (request, z: ZObject, bundle: Bundle) => {\n if (bundle.authData.apiKey) {\n // Use these lines to include the API key in the querystring\n request.params = request.params || {};\n request.params.api_key = bundle.authData.apiKey;\n\n // If you want to include the API key in the header instead, uncomment this:\n // request.headers.Authorization = bundle.authData.apiKey;\n }\n\n return request;\n};\n\nexport const befores = [includeApiKey];\n\nexport const afters = [handleBadResponses];\n\n```\n\n## `src/test/authentication.test.ts`\n\n```ts\nimport { describe, expect, it } from 'vitest';\nimport zapier from 'zapier-platform-core';\n\nimport App from '../index.js';\nconst appTester = zapier.createAppTester(App);\n\ndescribe('custom auth', () => {\n it('passes authentication and returns json', async () => {\n const bundle = {\n authData: {\n apiKey: 'secret',\n },\n };\n\n const response = await appTester(App.authentication.test, bundle);\n expect(response.data).toHaveProperty('username');\n });\n\n it('fails on bad auth', async () => {\n const bundle = {\n authData: {\n apiKey: 'bad',\n },\n };\n\n try {\n await appTester(App.authentication.test, bundle);\n } catch (error) {\n expect(error.message).toContain('The API Key you supplied is incorrect');\n return;\n }\n throw new Error('appTester should have thrown');\n });\n});\n\n```\n\n## `tsconfig.json`\n\n```json\n{\n \"compilerOptions\": {\n \"target\": \"ESNext\",\n \"module\": \"NodeNext\",\n \"moduleResolution\": \"NodeNext\",\n \"resolveJsonModule\": true,\n \"esModuleInterop\": true,\n \"noUncheckedIndexedAccess\": true,\n \"isolatedModules\": true,\n \"noImplicitAny\": false,\n \"skipLibCheck\": true,\n \"outDir\": \"./dist\",\n \"rootDir\": \"./src\",\n \"strict\": true\n },\n \"include\": [\"./src/**/*.ts\"],\n \"exclude\": [\"./**/*.test.ts\"]\n}\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/custom-auth-typescript", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/custom-auth-typescript", "section": "templates", "tags": ["custom-auth", "example", "template"], "related": ["zapier-platform init --template custom-auth-typescript"], "meta": {"files": ["README.md", "package.json", "tsconfig.json", "src/middleware.ts", "src/authentication.ts", "src/index.ts", "src/test/authentication.test.ts"], "auth": "custom-auth", "pattern": "example", "local": "repos/zapier-platform/example-apps/custom-auth-typescript"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:digest-auth", "kind": "template", "key": "digest-auth", "title": "Source template: digest-auth", "summary": "Full example-app source (digest-auth / example).", "body": "# example-app `digest-auth`\n\nAuth: `digest-auth` · Pattern: `example`\n\n## `README.md`\n\n```md\n# digest-auth\n\nThis Zapier integration project is generated by the `zapier-platform init` CLI command.\n\nThese are what you normally do next:\n\n```bash\n# Install dependencies\nnpm install # or you can use yarn\n\n# Run tests\nzapier-platform test\n\n# Register the integration on Zapier if you haven't\nzapier-platform register \"App Title\"\n\n# Or you can link to an existing integration on Zapier\nzapier-platform link\n\n# Push it to Zapier\nzapier-platform push\n```\n\nThen, to add more features, you can use the `zapier-platform scaffold` command, for example:\n\n```bash\n# Add a trigger\nzapier-platform scaffold trigger contact\n\n# Add an action\nzapier-platform scaffold create contact\n``` \n\nFind out more on the latest docs: https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md.\n\n```\n\n## `authentication.js`\n\n```js\n'use strict';\n\n// You want to make a request to an endpoint that is either specifically designed\n// to test auth, or one that every user will have access to. eg: `/me`.\n// By returning the entire request object, you have access to the request and\n// response data for testing purposes. Your connection label can access any data\n// from the returned response using the `json.` prefix. eg: `{{json.username}}`.\nconst test = (z, bundle) =>\n z.request({\n url: 'https://httpbin.zapier-tooling.com/digest-auth/auth/myuser/mypass',\n });\n\nmodule.exports = {\n // \"digest\" auth automatically creates \"username\" and \"password\" input fields. It\n // also registers default middleware to create the authentication header.\n type: 'digest',\n\n // Define any input app's auth requires here. The user will be prompted to enter\n // this info when they connect their account.\n fields: [],\n\n // The test method allows Zapier to verify that the credentials a user provides\n // are valid. We'll execute this method whenever a user connects their account for\n // the first time.\n test,\n\n // This template string can access all the data returned from the auth test. If\n // you return the test object, you'll access the returned data with a label like\n // `{{json.X}}`. If you return `response.data` from your test, then your label can\n // be `{{X}}`. This can also be a function that returns a label. That function has\n // the standard args `(z, bundle)` and data returned from the test can be accessed\n // in `bundle.inputData.X`.\n connectionLabel: '{{json.username}}',\n};\n\n```\n\n## `index.js`\n\n```js\nconst authentication = require('./authentication');\nconst { befores = [], afters = [] } = require('./middleware');\n\nmodule.exports = {\n // This is just shorthand to reference the installed dependencies you have.\n // Zapier will need to know these before we can upload.\n version: require('./package.json').version,\n platformVersion: require('zapier-platform-core').version,\n\n authentication,\n\n beforeRequest: [...befores],\n\n afterResponse: [...afters],\n\n // If you want your trigger to show up, you better include it here!\n triggers: {},\n\n // If you want your searches to show up, you better include it here!\n searches: {},\n\n // If you want your creates to show up, you better include it here!\n creates: {},\n\n resources: {},\n};\n\n```\n\n## `middleware.js`\n\n```js\n'use strict';\n\n// This function runs after every outbound request. You can use it to check for\n// errors or modify the response. You can have as many as you need. They'll need\n// to each be registered in your index.js file.\nconst handleBadResponses = (response, z, bundle) => {\n if (response.status === 401) {\n throw new z.errors.Error(\n // This message is surfaced to the user\n 'The username and/or password you supplied is incorrect',\n 'AuthenticationError',\n response.status,\n );\n }\n\n return response;\n};\n\nmodule.exports = { befores: [], afters: [handleBadResponses] };\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"digest-auth\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"jest --testTimeout 10000\"\n },\n \"dependencies\": {\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"jest\": \"^29.6.0\"\n },\n \"private\": true\n}\n\n```\n\n## `test/authentication.test.js`\n\n```js\n/* globals describe, it, expect */\n\nconst zapier = require('zapier-platform-core');\n\nconst App = require('../index');\nconst appTester = zapier.createAppTester(App);\n\ndescribe('digest auth', () => {\n it('correctly authenticates', async () => {\n // Try changing the values of username or password to see how the test method behaves\n const bundle = {\n authData: {\n username: 'myuser',\n password: 'mypass',\n },\n };\n\n const response = await appTester(App.authentication.test, bundle);\n\n expect(response.status).toBe(200);\n expect(response.data.authorized).toBe(true);\n expect(response.data.user).toBe('myuser');\n });\n\n it('fails on bad auth', async () => {\n // Try changing the values of username or password to see how the test method behaves\n const bundle = {\n authData: {\n username: 'user',\n password: 'badpwd',\n },\n };\n\n try {\n await appTester(App.authentication.test, bundle);\n } catch (err) {\n expect(err.message).toContain(\n 'The username and/or password you supplied is incorrect',\n );\n return;\n }\n throw new Error('appTester should have thrown');\n });\n});\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/digest-auth", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/digest-auth", "section": "templates", "tags": ["digest-auth", "example", "template"], "related": ["zapier-platform init --template digest-auth"], "meta": {"files": ["index.js", "README.md", "package.json", "middleware.js", "authentication.js", "test/authentication.test.js"], "auth": "digest-auth", "pattern": "example", "local": "repos/zapier-platform/example-apps/digest-auth"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:digest-auth-typescript", "kind": "template", "key": "digest-auth-typescript", "title": "Source template: digest-auth-typescript", "summary": "Full example-app source (digest-auth / example).", "body": "# example-app `digest-auth-typescript`\n\nAuth: `digest-auth` · Pattern: `example`\n\n## `README.md`\n\n```md\n# digest-auth-typescript\n\nThis Zapier integration project is generated by the `zapier-platform init` CLI command.\n\nThese are what you normally do next:\n\n```bash\n# Install dependencies\nnpm install # or you can use yarn\n\n# Run tests\nzapier-platform test\n\n# Register the integration on Zapier if you haven't\nzapier-platform register \"App Title\"\n\n# Or you can link to an existing integration on Zapier\nzapier-platform link\n\n# Push it to Zapier\nzapier-platform push\n```\n\nThen, to add more features, you can use the `zapier-platform scaffold` command, for example:\n\n```bash\n# Add a trigger\nzapier-platform scaffold trigger contact\n\n# Add an action\nzapier-platform scaffold create contact\n``` \n\nFind out more on the latest docs: https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md.\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"digest-auth-typescript\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"scripts\": {\n \"test\": \"npm run build && vitest --run\",\n \"clean\": \"rimraf ./dist ./build\",\n \"build\": \"npm run clean && tsc\",\n \"_zapier-build\": \"npm run build\"\n },\n \"dependencies\": {\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"rimraf\": \"^5.0.10\",\n \"typescript\": \"5.6.2\",\n \"vitest\": \"^2.1.2\"\n },\n \"private\": true,\n \"exports\": \"./dist/index.js\",\n \"type\": \"module\"\n}\n\n```\n\n## `src/authentication.ts`\n\n```ts\nimport type { ZObject, Bundle, Authentication } from 'zapier-platform-core';\n\n// You want to make a request to an endpoint that is either specifically designed\n// to test auth, or one that every user will have access to. eg: `/me`.\n// By returning the entire request object, you have access to the request and\n// response data for testing purposes. Your connection label can access any data\n// from the returned response using the `json.` prefix. eg: `{{json.username}}`.\nconst test = (z: ZObject, bundle: Bundle) =>\n z.request({\n url: 'https://httpbin.zapier-tooling.com/digest-auth/auth/myuser/mypass',\n });\n\nexport default {\n // \"digest\" auth automatically creates \"username\" and \"password\" input fields. It\n // also registers default middleware to create the authentication header.\n type: 'digest',\n\n // Define any input app's auth requires here. The user will be prompted to enter\n // this info when they connect their account.\n fields: [],\n\n // The test method allows Zapier to verify that the credentials a user provides\n // are valid. We'll execute this method whenever a user connects their account for\n // the first time.\n test,\n\n // This template string can access all the data returned from the auth test. If\n // you return the test object, you'll access the returned data with a label like\n // `{{json.X}}`. If you return `response.data` from your test, then your label can\n // be `{{X}}`. This can also be a function that returns a label. That function has\n // the standard args `(z: ZObject, bundle: Bundle)` and data returned from the\n // test can be accessed in `bundle.inputData.X`.\n connectionLabel: '{{json.username}}',\n} satisfies Authentication;\n\n```\n\n## `src/index.ts`\n\n```ts\nimport zapier, { defineApp } from 'zapier-platform-core';\n\nimport packageJson from '../package.json' with { type: 'json' };\n\nimport authentication from './authentication.js';\nimport { befores, afters } from './middleware.js';\n\nexport default defineApp({\n version: packageJson.version,\n platformVersion: zapier.version,\n\n authentication,\n beforeRequest: [...befores],\n afterResponse: [...afters],\n\n // Add your triggers here for them to show up!\n triggers: {},\n\n // Add your creates here for them to show up!\n creates: {},\n});\n\n```\n\n## `src/middleware.ts`\n\n```ts\nimport type { ZObject, Bundle, Authentication } from 'zapier-platform-core';\n\n// This function runs after every outbound request. You can use it to check for\n// errors or modify the response. You can have as many as you need. They'll need\n// to each be registered in your index.js file.\nconst handleBadResponses = (response, z: ZObject, bundle: Bundle) => {\n if (response.status === 401) {\n throw new z.errors.Error(\n // This message is surfaced to the user\n 'The username and/or password you supplied is incorrect',\n 'AuthenticationError',\n response.status,\n );\n }\n\n return response;\n};\n\nexport const befores = [];\n\nexport const afters = [handleBadResponses];\n\n```\n\n## `src/test/authentication.test.ts`\n\n```ts\nimport { describe, expect, it } from 'vitest';\nimport zapier from 'zapier-platform-core';\n\nimport App from '../index.js';\nconst appTester = zapier.createAppTester(App);\n\ndescribe('digest auth', () => {\n it('correctly authenticates', async () => {\n // Try changing the values of username or password to see how the test method behaves\n const bundle = {\n authData: {\n username: 'myuser',\n password: 'mypass',\n },\n };\n\n const response = await appTester(App.authentication.test, bundle);\n\n expect(response.status).toBe(200);\n expect(response.data.authorized).toBe(true);\n expect(response.data.user).toBe('myuser');\n });\n\n it('fails on bad auth', async () => {\n // Try changing the values of username or password to see how the test method behaves\n const bundle = {\n authData: {\n username: 'user',\n password: 'badpwd',\n },\n };\n\n try {\n await appTester(App.authentication.test, bundle);\n } catch (err) {\n expect(err.message).toContain(\n 'The username and/or password you supplied is incorrect',\n );\n return;\n }\n throw new Error('appTester should have thrown');\n });\n});\n\n```\n\n## `tsconfig.json`\n\n```json\n{\n \"compilerOptions\": {\n \"target\": \"ESNext\",\n \"module\": \"NodeNext\",\n \"moduleResolution\": \"NodeNext\",\n \"resolveJsonModule\": true,\n \"esModuleInterop\": true,\n \"noUncheckedIndexedAccess\": true,\n \"isolatedModules\": true,\n \"noImplicitAny\": false,\n \"skipLibCheck\": true,\n \"outDir\": \"./dist\",\n \"rootDir\": \"./src\",\n \"strict\": true\n },\n \"include\": [\"./src/**/*.ts\"],\n \"exclude\": [\"./**/*.test.ts\"]\n}\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/digest-auth-typescript", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/digest-auth-typescript", "section": "templates", "tags": ["digest-auth", "example", "template"], "related": ["zapier-platform init --template digest-auth-typescript"], "meta": {"files": ["README.md", "package.json", "tsconfig.json", "src/middleware.ts", "src/authentication.ts", "src/index.ts", "src/test/authentication.test.ts"], "auth": "digest-auth", "pattern": "example", "local": "repos/zapier-platform/example-apps/digest-auth-typescript"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:dynamic-dropdown", "kind": "template", "key": "dynamic-dropdown", "title": "Source template: dynamic-dropdown", "summary": "Full example-app source (n/a / dynamic-dropdown).", "body": "# example-app `dynamic-dropdown`\n\nAuth: `n/a` · Pattern: `dynamic-dropdown`\n\n## `README.md`\n\n```md\n# dynamic-dropdown\n\nThis Zapier integration project is generated by the `zapier-platform init` CLI command.\n\nThese are what you normally do next:\n\n```bash\n# Install dependencies\nnpm install # or you can use pnpm or yarn\n\n# Run tests\nzapier-platform test\n\n# Register the integration on Zapier if you haven't\nzapier-platform register \"App Title\"\n\n# Or you can link to an existing integration on Zapier\nzapier-platform link\n\n# Push it to Zapier\nzapier-platform push\n```\n\nThen, to add more features, you can use the `zapier-platform scaffold` command, for example:\n\n```bash\n# Add a trigger\nzapier-platform scaffold trigger contact\n\n# Add an action\nzapier-platform scaffold create contact\n``` \n\nFind out more on the latest docs: https://docs.zapier.com/platform\n\n# dynamic-dropdown\n\nThis example integration demonstrates how to create **dynamic dropdowns** (also known as dynamic choices) in Zapier integrations.\n\n## Dynamic Dropdown Patterns\n\nThere are two ways to implement dynamic dropdowns:\n\n### 1. Trigger-based (Legacy Pattern)\n\nUses a separate trigger to fetch choices. Reference it with the `dynamic` property:\n\n```javascript\n{\n key: 'species_id',\n type: 'integer',\n label: 'Species',\n dynamic: 'species.id.name', // Format: \"triggerKey.idField.labelField\"\n}\n```\n\nThe trigger (`species`) fetches data, and Zapier uses `id` for the value and `name` for the display label.\n\n### 2. Perform-based (New Pattern)\n\nUses a function to fetch choices directly. Define it with `choices.perform`:\n\n```javascript\n{\n key: 'planet_id',\n type: 'integer',\n label: 'Home Planet',\n resource: 'planet', // Explicit resource linking (see below)\n choices: {\n perform: getPlanetChoices,\n },\n}\n```\n\n#### Resource Linking\n\nThe `resource` property explicitly links an input field to a resource. This is particularly important for perform-based dropdowns since they don't have a `dynamic` property to derive the resource from.\n\n```javascript\n{\n key: 'spreadsheet_id',\n resource: 'spreadsheet',\n choices: { perform: getSpreadsheets },\n}\n```\n\nThe perform function must return:\n\n```javascript\n{\n results: [\n { id: '1', label: 'Tatooine' },\n { id: '2', label: 'Alderaan' },\n ],\n paging_token: 'https://api.example.com/planets?page=2', // or null if no more pages\n}\n```\n\n#### Pagination Support\n\nThe perform function receives `bundle.meta.paging_token` for subsequent page requests:\n\n```javascript\nconst getPlanetChoices = async (z, bundle) => {\n // First request: paging_token is undefined\n // Subsequent requests: paging_token is the value you returned previously\n const url = bundle.meta.paging_token || 'https://api.example.com/planets';\n\n const response = await z.request({ url });\n\n return {\n results: response.data.results.map((item) => ({\n id: item.id,\n label: item.name,\n })),\n // Return null when there are no more pages\n paging_token: response.data.next,\n };\n};\n```\n\n## This Example\n\nThis integration uses the [Star Wars API](https://swapi.dev/) to demonstrate:\n\n- **Species dropdown** - Trigger-based pattern using the `species` trigger\n- **Planet dropdown** - Perform-based pattern with pagination and explicit `resource` linking\n\n## Getting Started\n\n```bash\n# Install dependencies\nnpm install\n\n# Run tests\nzapier-platform test\n\n# Push to Zapier\nzapier-platform push\n```\n\nFind out more on the latest docs: https://docs.zapier.com/platform\n\n```\n\n## `index.js`\n\n```js\nconst people = require('./triggers/people');\nconst species = require('./triggers/species');\n\nmodule.exports = {\n version: require('./package.json').version,\n platformVersion: require('zapier-platform-core').version,\n\n triggers: {\n [people.key]: people,\n [species.key]: species,\n },\n};\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"dynamic-dropdown\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"scripts\": {\n \"test\": \"jest --testTimeout 10000\"\n },\n \"dependencies\": {\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"jest\": \"^29.6.0\"\n },\n \"private\": true,\n \"main\": \"index.js\"\n}\n\n```\n\n## `test/triggers.test.js`\n\n```js\n/* globals describe, expect, test */\n\nconst zapier = require('zapier-platform-core');\n\nconst App = require('../index');\nconst appTester = zapier.createAppTester(App);\nzapier.tools.env.inject();\n\ndescribe('triggers', () => {\n test('species', async () => {\n const bundle = {\n inputData: {},\n meta: {},\n };\n\n const results = await appTester(\n App.triggers.species.operation.perform,\n bundle,\n );\n expect(results.length).toBeGreaterThan(1);\n\n const firstSpecies = results[0];\n expect(firstSpecies.id).toBe(1);\n expect(firstSpecies.name).toBe('Human');\n });\n\n test('people', async () => {\n const bundle = {\n inputData: {\n species: 1,\n },\n };\n\n const results = await appTester(\n App.triggers.people.operation.perform,\n bundle,\n );\n expect(results.length).toBeGreaterThan(1);\n\n const firstPerson = results[0];\n expect(firstPerson.id).toBe(1);\n expect(firstPerson.name).toBe('Luke Skywalker');\n });\n});\n\n```\n\n## `triggers/people.js`\n\n```js\nconst { extractID } = require('../utils');\n\n/**\n * PERFORM-BASED choices WITH PAGINATION (NEW pattern)\n * Fetches planets from the Star Wars API with pagination support.\n *\n * - bundle.meta.paging_token is a full URL from the previous response\n * - Return paging_token as the API's next page URL (or null if no more pages)\n *\n * MUST return: { results: [...], paging_token: string|null }\n */\nconst getPlanetChoices = async (z, bundle) => {\n // paging_token is a full URL to the next page (from SWAPI's \"next\" field)\n // First page: paging_token is undefined/null, use default URL\n const url = bundle.meta.paging_token || 'https://swapi.dev/api/planets/';\n\n const response = await z.request({ url });\n const data = response.data;\n\n // SWAPI returns: { results: [...], next: \"url\" or null }\n return {\n results: data.results.map((planet) => ({\n id: extractID(planet.url),\n label: planet.name,\n })),\n // Return SWAPI's next URL as our paging_token\n paging_token: data.next,\n };\n};\n\n// Fetches a list of records from the endpoint\nconst perform = async (z, bundle) => {\n // Ideally, we should poll through all the pages of results, but in this\n // example we're going to omit that part. Thus, this trigger only \"see\" the\n // people in their first page of results.\n const response = await z.request({ url: 'https://swapi.info/api/people/' });\n let peopleArray = response.data;\n\n if (bundle.inputData.species_id) {\n // The Zap's setup has requested a specific species of person. Since the\n // API/endpoint can't perform the filtering, we'll perform it here, within\n // the integration, and return the matching objects/records back to Zapier.\n peopleArray = peopleArray.filter((person) => {\n let speciesID;\n if (!person.species || !person.species.length) {\n speciesID = 1; // Assume human if species is not provided\n } else {\n speciesID = extractID(person.species[0]);\n }\n return speciesID === bundle.inputData.species_id;\n });\n }\n\n if (bundle.inputData.planet_id) {\n // The Zap's setup has requested a specific home planet. Filter people by\n // homeworld (SWAPI people have a homeworld URL).\n peopleArray = peopleArray.filter((person) => {\n if (!person.homeworld) return false;\n const homeworldID = extractID(person.homeworld);\n return homeworldID === bundle.inputData.planet_id;\n });\n }\n\n return peopleArray.map((person) => {\n person.id = extractID(person.url);\n return person;\n });\n};\n\nmodule.exports = {\n key: 'people',\n noun: 'person',\n display: {\n label: 'New Person',\n description: 'Triggers when a new person is added.',\n },\n\n operation: {\n inputFields: [\n // TRIGGER-BASED dynamic dropdown (legacy pattern)\n // Uses a separate trigger to fetch choices\n {\n key: 'species_id',\n type: 'integer',\n label: 'Species (trigger-based)',\n helpText:\n 'Filter by species. Uses trigger-based dynamic dropdown (dynamic: \"species.id.name\").',\n dynamic: 'species.id.name',\n altersDynamicFields: true,\n },\n // PERFORM-BASED dynamic dropdown WITH PAGINATION (new pattern)\n // Uses a function to fetch choices directly\n {\n key: 'planet_id',\n type: 'integer',\n label: 'Home Planet (perform-based)',\n helpText:\n 'Filter by home planet. Uses perform-based dynamic dropdown with pagination support.',\n resource: 'planet', // Explicit resource linking for perform-based dropdowns\n choices: {\n perform: getPlanetChoices,\n },\n },\n ],\n perform,\n sample: {\n id: '1',\n name: 'Luke Skywalker',\n birth_year: '19 BBY',\n eye_color: 'Blue',\n gender: 'Male',\n hair_color: 'Blond',\n height: '172',\n mass: '77',\n skin_color: 'Fair',\n created: '2014-12-09T13:50:51.644000Z',\n edited: '2014-12-10T13:52:43.172000Z',\n },\n },\n};\n\n```\n\n## `triggers/species.js`\n\n```js\nconst { extractID } = require('../utils');\n\n// Fetches a list of records from the endpoint\nconst perform = async (z, bundle) => {\n const request = {\n url: 'https://swapi.info/api/species/',\n params: {},\n };\n\n // This API returns things in \"pages\" of results\n if (bundle.meta.page) {\n request.params.page = 1 + bundle.meta.page;\n }\n\n const response = await z.request(request);\n const speciesArray = response.data;\n return speciesArray.map((species) => {\n species.id = extractID(species.url);\n return species;\n });\n};\n\nmodule.exports = {\n key: 'species',\n noun: 'Species',\n display: {\n label: 'List of Species',\n description:\n 'This is a hidden trigger, and is used in a Dynamic Dropdown of another trigger.',\n hidden: true,\n },\n\n operation: {\n // Since this is a \"hidden\" trigger, there aren't any inputFields needed\n perform,\n // The folowing is a \"hint\" to the Zap Editor that this trigger returns data\n // \"in pages\", and that the UI should display an option to \"load more\" to\n // the human.\n canPaginate: true,\n },\n};\n\n```\n\n## `utils.js`\n\n```js\n// Some handy stuff that's used in various places\n\n// Extract the numeric ID from a URL like 'https://swapi.dev/api/people/1/'\nconst extractID = (urlString) => {\n const match = urlString.match(/\\/(\\d+)\\/?$/);\n if (match) {\n return parseInt(match[1]);\n }\n throw new Error(`ID not found in URL: ${urlString}`);\n};\n\nmodule.exports = { extractID };\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/dynamic-dropdown", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/dynamic-dropdown", "section": "templates", "tags": ["dynamic-dropdown", "example", "template"], "related": [], "meta": {"files": ["index.js", "README.md", "package.json", "utils.js", "test/triggers.test.js", "triggers/species.js", "triggers/people.js"], "auth": null, "pattern": "dynamic-dropdown", "local": "repos/zapier-platform/example-apps/dynamic-dropdown"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:files", "kind": "template", "key": "files", "title": "Source template: files", "summary": "Full example-app source (n/a / files).", "body": "# example-app `files`\n\nAuth: `n/a` · Pattern: `files`\n\n## `README.md`\n\n```md\n# files\n\nThis Zapier integration project is generated by the `zapier-platform init` CLI command.\n\nThese are what you normally do next:\n\n```bash\n# Install dependencies\nnpm install # or you can use yarn\n\n# Run tests\nzapier-platform test\n\n# Register the integration on Zapier if you haven't\nzapier-platform register \"App Title\"\n\n# Or you can link to an existing integration on Zapier\nzapier-platform link\n\n# Push it to Zapier\nzapier-platform push\n```\n\nFind out more on the latest docs: https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md.\n\n# The \"files\" Template\n\nThis example has a trigger and a create showcasing file handling.\n\nFind out more in the docs: https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#stashing-files.\n\n```\n\n## `creates/uploadFile_v10.js`\n\n```js\nconst http = require('https'); // require('http') if your URL is not https\n\nconst FormData = require('form-data');\n\n// Getting a stream directly from http. This only works on core 10+. For core\n// 9.x compatible code, see uploadFile_v9.js.\nconst makeDownloadStream = (url) =>\n new Promise((resolve, reject) => {\n http\n .request(url, (res) => {\n // We can risk missing the first n bytes if we don't pause!\n res.pause();\n resolve(res);\n })\n .on('error', reject)\n .end();\n });\n\nconst perform = async (z, bundle) => {\n // bundle.inputData.file will in fact be an URL where the file data can be\n // downloaded from which we do via a stream\n const stream = await makeDownloadStream(bundle.inputData.file, z);\n\n const form = new FormData();\n form.append('filename', bundle.inputData.filename);\n form.append('file', stream);\n\n // All set! Resume the stream\n stream.resume();\n\n const response = await z.request({\n url: 'https://auth-json-server.zapier-staging.com/upload',\n method: 'POST',\n body: form,\n headers: {\n // DO NOT do auth like this! We do this here because this is a file\n // uploading example so the auth is not the point.\n 'x-api-key': 'secret',\n },\n });\n\n return response.data;\n};\n\nmodule.exports = {\n key: 'uploadFile_v10',\n noun: 'File',\n display: {\n label: 'Upload File v10',\n description: 'Uploads a file. Only works on zapier-platform-core v10+.',\n },\n operation: {\n inputFields: [\n { key: 'filename', required: true, type: 'string', label: 'Filename' },\n { key: 'file', required: true, type: 'file', label: 'File' },\n ],\n perform,\n sample: {\n id: 1,\n filename: 'example.pdf',\n file: 'SAMPLE FILE',\n },\n },\n};\n\n```\n\n## `creates/uploadFile_v9.js`\n\n```js\nconst { randomBytes } = require('crypto');\nconst fs = require('fs');\nconst os = require('os');\nconst path = require('path');\n\nconst fetch = require('node-fetch');\nconst FormData = require('form-data');\n\n// Download the HTTP URL to a local temporary file, and make a readable stream\n// from it. This should work compatibly for all core versions. But if you're\n// using core v10+, we recommend to use the implementation of uploadFile_v10.js.\nconst makeDownloadStream = async (url) => {\n // Create a temp file to store the downloaded file\n const filename = randomBytes(16).toString('hex');\n const tmpFilePath = path.join(os.tmpdir(), filename);\n const dest = fs.createWriteStream(tmpFilePath);\n\n const response = await fetch(url);\n\n // Download the file to the temp file. When finished, open a readable stream\n // from that temp file.\n return new Promise((resolve, reject) => {\n response.body\n .pipe(dest)\n .on('close', () => {\n const stream = fs.createReadStream(tmpFilePath).on('close', () => {\n // Delete the file once the stream is read\n fs.unlinkSync(tmpFilePath);\n });\n resolve(stream);\n })\n .on('error', reject);\n });\n};\n\nconst perform = async (z, bundle) => {\n const form = new FormData();\n\n form.append('filename', bundle.inputData.filename);\n\n // bundle.inputData.file will in fact be an URL where the file data can be\n // downloaded from which we do via a stream\n const stream = await makeDownloadStream(bundle.inputData.file, z);\n form.append('file', stream);\n\n const response = await z.request({\n url: 'https://auth-json-server.zapier-staging.com/upload',\n method: 'POST',\n body: form,\n headers: {\n // DO NOT do auth like this! We do this here because this is a file\n // uploading example so the auth is not the point.\n 'x-api-key': 'secret',\n },\n });\n\n return response.json;\n};\n\nmodule.exports = {\n key: 'uploadFile_v9',\n noun: 'File',\n display: {\n label: 'Upload File v9',\n description:\n 'Uploads a file. Compatible with all versions of zapier-platform-core.',\n },\n operation: {\n inputFields: [\n { key: 'filename', required: true, type: 'string', label: 'Filename' },\n { key: 'file', required: true, type: 'file', label: 'File' },\n ],\n perform,\n sample: {\n id: 1,\n filename: 'example.pdf',\n file: 'SAMPLE FILE',\n },\n },\n};\n\n```\n\n## `hydrators.js`\n\n```js\nmodule.exports = {\n downloadFile: async (z, bundle) => {\n // Use standard auth to request the file\n const filePromise = z.request({\n url: bundle.inputData.url,\n raw: true,\n });\n\n // When `raw` is true, the result of z.request() can be passed to\n // z.stashFile(). z.stashFile() will upload the file to a Zapier-owned S3\n // bucket and return a promise of an S3 URL that allows Zapier to get the\n // file without auth. If your file URL is permanently publicly available,\n // you may skip z.stashFile() and return that URL directly here.\n return z.stashFile(filePromise);\n },\n};\n\n```\n\n## `index.js`\n\n```js\nconst hydrators = require('./hydrators');\nconst newFile = require('./triggers/newFile');\nconst uploadFileV10 = require('./creates/uploadFile_v10');\nconst uploadFileV9 = require('./creates/uploadFile_v9');\n\nmodule.exports = {\n // This is just shorthand to reference the installed dependencies you have.\n // Zapier will need to know these before we can upload.\n version: require('./package.json').version,\n platformVersion: require('zapier-platform-core').version,\n\n // Any hydrators go here\n hydrators,\n\n // If you want your triggers to show up, you better include it here!\n triggers: {\n [newFile.key]: newFile,\n },\n\n // If you want your creates to show up, you better include it here!\n creates: {\n [uploadFileV10.key]: uploadFileV10,\n [uploadFileV9.key]: uploadFileV9,\n },\n};\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"files\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"jest --testTimeout 10000\"\n },\n \"dependencies\": {\n \"zapier-platform-core\": \"19.1.0\",\n \"form-data\": \"4.0.0\"\n },\n \"devDependencies\": {\n \"jest\": \"^26.6.3\"\n },\n \"private\": true\n}\n\n```\n\n## `test/creates.test.js`\n\n```js\n/* globals describe, expect, test */\n\nconst zapier = require('zapier-platform-core');\n\nconst App = require('../index');\nconst appTester = zapier.createAppTester(App);\nzapier.tools.env.inject();\n\nconst CORE_VERSION = zapier.version.split('.').map((s) => parseInt(s));\n\nconst FILE_URL =\n 'https://cdn.zapier.com/storage/files/f6679cf77afeaf6b8426de8d7b9642fc.pdf';\n\n// This is what you get when doing `curl <FILE_URL> | sha1sum`\nconst EXPECTED_SHA1 = '3cf58b42a0fb1b7cc58de8110096841ece967530';\n\ndescribe('uploadFile', () => {\n test('upload file v10', async () => {\n if (CORE_VERSION[0] < 10) {\n console.warn(\n `skipped because this only works on core v10+ and you're on ${zapier.version}`,\n );\n return;\n }\n\n const bundle = {\n inputData: {\n filename: 'sample.pdf',\n\n // in production, this will be an hydration URL to the selected file's data\n file: FILE_URL,\n },\n };\n\n const result = await appTester(\n App.creates.uploadFile_v10.operation.perform,\n bundle,\n );\n expect(result.filename).toBe('sample.pdf');\n expect(result.file.sha1).toBe(EXPECTED_SHA1);\n });\n\n test('upload file v9', async () => {\n const bundle = {\n inputData: {\n filename: 'sample.pdf',\n\n // in production, this will be an hydration URL to the selected file's data\n file: FILE_URL,\n },\n };\n\n const result = await appTester(\n App.creates.uploadFile_v9.operation.perform,\n bundle,\n );\n expect(result.filename).toBe('sample.pdf');\n expect(result.file.sha1).toBe(EXPECTED_SHA1);\n });\n});\n\n```\n\n## `test/hydrators.test.js`\n\n```js\n/* globals describe, expect, test */\n\nconst zapier = require('zapier-platform-core');\n\nconst App = require('../index');\nconst appTester = zapier.createAppTester(App);\nzapier.tools.env.inject();\n\ndescribe('downloadFile', () => {\n test('download file', async () => {\n if (!process.env.ZAPIER_DEPLOY_KEY) {\n console.warn('skipped as ZAPIER_DEPLOY_KEY is not defined');\n return;\n }\n\n const bundle = {\n inputData: {\n url: 'https://httpbin.zapier-tooling.com/xml',\n },\n };\n\n const url = await appTester(App.hydrators.downloadFile, bundle);\n expect(url).toContain(\n 'https://zapier-dev-files.s3.amazonaws.com/cli-platform/',\n );\n });\n});\n\n```\n\n## `test/triggers.test.js`\n\n```js\n/* globals describe, expect, test */\n\nconst zapier = require('zapier-platform-core');\n\nconst App = require('../index');\nconst appTester = zapier.createAppTester(App);\nzapier.tools.env.inject();\n\ndescribe('newFile', () => {\n test('fetch files', async () => {\n const bundle = {};\n const results = await appTester(\n App.triggers.newFile.operation.perform,\n bundle,\n );\n\n expect(results.length).toBeGreaterThan(0);\n\n // The 'hydrate|||' thing how Zapier represents dehydrated data\n const firstFile = results[0];\n expect(firstFile).toEqual({\n id: expect.stringMatching(/^https:/),\n file: expect.stringMatching(/^hydrate\\|\\|\\|/),\n });\n });\n});\n\n```\n\n## `triggers/newFile.js`\n\n```js\nconst hydrators = require('../hydrators');\n\nconst perform = (z, bundle) => {\n // In reality you're more likely to get file info from a remote server. Here\n // we're hard coding some links just to demonstrate.\n const fileURLs = [\n 'https://httpbin.zapier-tooling.com/image/png',\n 'https://httpbin.zapier-tooling.com/image/jpeg',\n 'https://httpbin.zapier-tooling.com/xml',\n ];\n\n return fileURLs.map((fileURL) => {\n const fileInfo = {\n id: fileURL,\n\n // Make it possible to get the actual file contents if necessary. No need\n // to make the request to download files now when the trigger is run.\n file: z.dehydrateFile(hydrators.downloadFile, { url: fileURL }),\n };\n return fileInfo;\n });\n};\n\n// We recommend writing your triggers separate like this and rolling them into\n// the App definition at the end.\nmodule.exports = {\n key: 'newFile',\n\n // You'll want to provide some helpful display labels and descriptions\n // for users. Zapier will put them into the UX.\n noun: 'File',\n display: {\n label: 'New File',\n description: 'Triggers when a new file is added.',\n },\n\n // `operation` is where the business logic goes.\n operation: {\n perform,\n\n sample: {\n id: 'https://example.com/file.txt',\n file: 'content',\n },\n },\n};\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/files", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/files", "section": "templates", "tags": ["example", "files", "template"], "related": ["zapier-platform init --template files"], "meta": {"files": ["hydrators.js", "index.js", "README.md", "package.json", "creates/uploadFile_v10.js", "creates/uploadFile_v9.js", "test/triggers.test.js", "test/creates.test.js", "test/hydrators.test.js", "triggers/newFile.js"], "auth": null, "pattern": "files", "local": "repos/zapier-platform/example-apps/files"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:github", "kind": "template", "key": "github", "title": "Source template: github", "summary": "Full example-app source (n/a / example).", "body": "# example-app `github`\n\nAuth: `n/a` · Pattern: `example`\n\n## `README.md`\n\n```md\n# zapier-platform-example-app-github\n\nAn example app that helps kickstart your journey as a Zapier [developer](https://developer.zapier.com/). Once logged in, you can see the tutorial itself [here](https://developer.zapier.com/cli-guide/introduction).\n\nYou can learn more about the CLI [here](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md).\n\n```\n\n## `authentication.js`\n\n```js\nconst getAccessToken = async (z, bundle) => {\n const response = await z.request({\n url: 'https://github.com/login/oauth/access_token',\n method: 'POST',\n body: {\n client_id: process.env.CLIENT_ID,\n client_secret: process.env.CLIENT_SECRET,\n grant_type: 'authorization_code',\n code: bundle.inputData.code,\n\n // Extra data can be pulled from the querystring. For instance:\n // 'accountDomain': bundle.cleanedRequest.querystring.accountDomain\n },\n headers: {\n 'content-type': 'application/x-www-form-urlencoded',\n Accept: 'application/json',\n },\n });\n\n // If you're using core v9.x or older, you should call response.throwForStatus()\n // or verify response.status === 200 before you continue.\n\n // This function should return `access_token`.\n // If your app does an app refresh, then `refresh_token` should be returned here\n // as well\n\n return {\n access_token: response.data.access_token,\n };\n};\n\n// This function runs before every outbound request. You can have as many as you\n// need. They'll need to each be registered in your index.js file.\nconst includeBearerToken = (request, z, bundle) => {\n if (bundle.authData.access_token) {\n request.headers.Authorization = `Bearer ${bundle.authData.access_token}`;\n }\n\n return request;\n};\n\n// You want to make a request to an endpoint that is either specifically designed\n// to test auth, or one that every user will have access to. eg: `/me`.\n// By returning the entire request object, you have access to the request and\n// response data for testing purposes. Your connection label can access any data\n// from the returned response using the `json.` prefix. eg: `{{json.username}}`.\nconst test = async (z, bundle) => {\n const response = await z.request({ url: 'https://api.github.com/user' });\n return response;\n};\n\nmodule.exports = {\n config: {\n // OAuth2 is a web authentication standard. There are a lot of configuration\n // options that will fit most any situation.\n type: 'oauth2',\n oauth2Config: {\n authorizeUrl: {\n url: 'https://github.com/login/oauth/authorize',\n params: {\n client_id: '{{process.env.CLIENT_ID}}',\n state: '{{bundle.inputData.state}}',\n redirect_uri: '{{bundle.inputData.redirect_uri}}',\n response_type: 'code',\n },\n },\n getAccessToken,\n },\n\n // Define any input app's auth requires here. The user will be prompted to enter\n // this info when they connect their account.\n fields: [],\n\n // The test method allows Zapier to verify that the credentials a user provides\n // are valid. We'll execute this method whenever a user connects their account for\n // the first time.\n test,\n\n // This template string can access all the data returned from the auth test. If\n // you return the test object, you'll access the returned data with a label like\n // `{{json.X}}`. If you return `response.data` from your test, then your label can\n // be `{{X}}`. This can also be a function that returns a label. That function has\n // the standard args `(z, bundle)` and data returned from the test can be accessed\n // in `bundle.inputData.X`.\n connectionLabel: '{{json.login}}',\n },\n befores: [includeBearerToken],\n afters: [],\n};\n\n```\n\n## `creates/issue.js`\n\n```js\nconst sample = require('../samples/sample_issue');\n\nconst createIssue = (z, bundle) => {\n const responsePromise = z.request({\n method: 'POST',\n url: `https://api.github.com/repos/${bundle.inputData.repo}/issues`,\n body: {\n title: bundle.inputData.title,\n body: bundle.inputData.body,\n },\n });\n return responsePromise.then((response) => response.data);\n};\n\nmodule.exports = {\n key: 'issue',\n noun: 'Issue',\n\n display: {\n label: 'Create Issue',\n description: 'Creates an issue.',\n },\n\n operation: {\n inputFields: [\n {\n key: 'repo',\n label: 'Repo',\n required: true,\n dynamic: 'repo.full_name.full_name',\n },\n { key: 'title', label: 'Title', required: true },\n { key: 'body', label: 'Body', required: false },\n ],\n perform: createIssue,\n sample: sample,\n },\n};\n\n```\n\n## `index.js`\n\n```js\nconst repoTrigger = require('./triggers/repo');\nconst issueCreate = require('./creates/issue');\nconst issueTrigger = require('./triggers/issue');\nconst {\n config: authentication,\n befores = [],\n afters = [],\n} = require('./authentication');\n\nconst App = {\n // This is just shorthand to reference the installed dependencies you have. Zapier will\n // need to know these before we can upload\n version: require('./package.json').version,\n platformVersion: require('zapier-platform-core').version,\n authentication,\n\n // beforeRequest & afterResponse are optional hooks into the provided HTTP client\n beforeRequest: [...befores],\n\n afterResponse: [...afters],\n\n // If you want to define optional resources to simplify creation of triggers, searches, creates - do that here!\n resources: {},\n\n // If you want your trigger to show up, you better include it here!\n triggers: {\n [repoTrigger.key]: repoTrigger,\n [issueTrigger.key]: issueTrigger,\n },\n\n // If you want your searches to show up, you better include it here!\n searches: {},\n\n // If you want your creates to show up, you better include it here!\n creates: {\n [issueCreate.key]: issueCreate,\n },\n};\n\n// Finally, export the app.\nmodule.exports = App;\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"zapier-platform-example-app-github\",\n \"version\": \"1.0.0\",\n \"description\": \"An example app for the Zapier platform.\",\n \"repository\": \"zapier/zapier-platform-app-github-example\",\n \"homepage\": \"https://zapier.com/developer\",\n \"author\": \"Zane Lyon <zane.lyon@zapier.com>\",\n \"license\": \"BSD-3-Clause\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"jest --testTimeout 10000\"\n },\n \"engines\": {\n \"node\": \"8.10.0\",\n \"npm\": \">=5.6.0\"\n },\n \"dependencies\": {\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"jest\": \"^26.6.3\",\n \"nock\": \"^13.1.3\"\n }\n}\n\n```\n\n## `samples/sample_issue.js`\n\n```js\nmodule.exports = {\n id: 1,\n url: 'https://api.github.com/repos/octocat/Hello-World/issues/1347',\n repository_url: 'https://api.github.com/repos/octocat/Hello-World',\n labels_url:\n 'https://api.github.com/repos/octocat/Hello-World/issues/1347/labels{/name}',\n comments_url:\n 'https://api.github.com/repos/octocat/Hello-World/issues/1347/comments',\n events_url:\n 'https://api.github.com/repos/octocat/Hello-World/issues/1347/events',\n html_url: 'https://github.com/octocat/Hello-World/issues/1347',\n number: 1347,\n state: 'open',\n title: 'Found a bug',\n body: \"I'm having a problem with this.\",\n user: {\n login: 'octocat',\n id: 1,\n avatar_url: 'https://github.com/images/error/octocat_happy.gif',\n gravatar_id: '',\n url: 'https://api.github.com/users/octocat',\n html_url: 'https://github.com/octocat',\n followers_url: 'https://api.github.com/users/octocat/followers',\n following_url:\n 'https://api.github.com/users/octocat/following{/other_user}',\n gists_url: 'https://api.github.com/users/octocat/gists{/gist_id}',\n starred_url: 'https://api.github.com/users/octocat/starred{/owner}{/repo}',\n subscriptions_url: 'https://api.github.com/users/octocat/subscriptions',\n organizations_url: 'https://api.github.com/users/octocat/orgs',\n repos_url: 'https://api.github.com/users/octocat/repos',\n events_url: 'https://api.github.com/users/octocat/events{/privacy}',\n received_events_url: 'https://api.github.com/users/octocat/received_events',\n type: 'User',\n site_admin: false,\n },\n labels: [\n {\n id: 208045946,\n url: 'https://api.github.com/repos/octocat/Hello-World/labels/bug',\n name: 'bug',\n color: 'f29513',\n default: true,\n },\n ],\n assignee: {\n login: 'octocat',\n id: 1,\n avatar_url: 'https://github.com/images/error/octocat_happy.gif',\n gravatar_id: '',\n url: 'https://api.github.com/users/octocat',\n html_url: 'https://github.com/octocat',\n followers_url: 'https://api.github.com/users/octocat/followers',\n following_url:\n 'https://api.github.com/users/octocat/following{/other_user}',\n gists_url: 'https://api.github.com/users/octocat/gists{/gist_id}',\n starred_url: 'https://api.github.com/users/octocat/starred{/owner}{/repo}',\n subscriptions_url: 'https://api.github.com/users/octocat/subscriptions',\n organizations_url: 'https://api.github.com/users/octocat/orgs',\n repos_url: 'https://api.github.com/users/octocat/repos',\n events_url: 'https://api.github.com/users/octocat/events{/privacy}',\n received_events_url: 'https://api.github.com/users/octocat/received_events',\n type: 'User',\n site_admin: false,\n },\n assignees: [\n {\n login: 'octocat',\n id: 1,\n avatar_url: 'https://github.com/images/error/octocat_happy.gif',\n gravatar_id: '',\n url: 'https://api.github.com/users/octocat',\n html_url: 'https://github.com/octocat',\n followers_url: 'https://api.github.com/users/octocat/followers',\n following_url:\n 'https://api.github.com/users/octocat/following{/other_user}',\n gists_url: 'https://api.github.com/users/octocat/gists{/gist_id}',\n starred_url:\n 'https://api.github.com/users/octocat/starred{/owner}{/repo}',\n subscriptions_url: 'https://api.github.com/users/octocat/subscriptions',\n organizations_url: 'https://api.github.com/users/octocat/orgs',\n repos_url: 'https://api.github.com/users/octocat/repos',\n events_url: 'https://api.github.com/users/octocat/events{/privacy}',\n received_events_url:\n 'https://api.github.com/users/octocat/received_events',\n type: 'User',\n site_admin: false,\n },\n ],\n milestone: {\n url: 'https://api.github.com/repos/octocat/Hello-World/milestones/1',\n html_url: 'https://github.com/octocat/Hello-World/milestones/v1.0',\n labels_url:\n 'https://api.github.com/repos/octocat/Hello-World/milestones/1/labels',\n id: 1002604,\n number: 1,\n state: 'open',\n title: 'v1.0',\n description: 'Tracking milestone for version 1.0',\n creator: {\n login: 'octocat',\n id: 1,\n avatar_url: 'https://github.com/images/error/octocat_happy.gif',\n gravatar_id: '',\n url: 'https://api.github.com/users/octocat',\n html_url: 'https://github.com/octocat',\n followers_url: 'https://api.github.com/users/octocat/followers',\n following_url:\n 'https://api.github.com/users/octocat/following{/other_user}',\n gists_url: 'https://api.github.com/users/octocat/gists{/gist_id}',\n starred_url:\n 'https://api.github.com/users/octocat/starred{/owner}{/repo}',\n subscriptions_url: 'https://api.github.com/users/octocat/subscriptions',\n organizations_url: 'https://api.github.com/users/octocat/orgs',\n repos_url: 'https://api.github.com/users/octocat/repos',\n events_url: 'https://api.github.com/users/octocat/events{/privacy}',\n received_events_url:\n 'https://api.github.com/users/octocat/received_events',\n type: 'User',\n site_admin: false,\n },\n open_issues: 4,\n closed_issues: 8,\n created_at: '2011-04-10T20:09:31Z',\n updated_at: '2014-03-03T18:58:10Z',\n closed_at: '2013-02-12T13:22:01Z',\n due_on: '2012-10-09T23:39:01Z',\n },\n locked: false,\n comments: 0,\n pull_request: {\n url: 'https://api.github.com/repos/octocat/Hello-World/pulls/1347',\n html_url: 'https://github.com/octocat/Hello-World/pull/1347',\n diff_url: 'https://github.com/octocat/Hello-World/pull/1347.diff',\n patch_url: 'https://github.com/octocat/Hello-World/pull/1347.patch',\n },\n closed_at: null,\n created_at: '2011-04-22T13:33:48Z',\n updated_at: '2011-04-22T13:33:48Z',\n closed_by: {\n login: 'octocat',\n id: 1,\n avatar_url: 'https://github.com/images/error/octocat_happy.gif',\n gravatar_id: '',\n url: 'https://api.github.com/users/octocat',\n html_url: 'https://github.com/octocat',\n followers_url: 'https://api.github.com/users/octocat/followers',\n following_url:\n 'https://api.github.com/users/octocat/following{/other_user}',\n gists_url: 'https://api.github.com/users/octocat/gists{/gist_id}',\n starred_url: 'https://api.github.com/users/octocat/starred{/owner}{/repo}',\n subscriptions_url: 'https://api.github.com/users/octocat/subscriptions',\n organizations_url: 'https://api.github.com/users/octocat/orgs',\n repos_url: 'https://api.github.com/users/octocat/repos',\n events_url: 'https://api.github.com/users/octocat/events{/privacy}',\n received_events_url: 'https://api.github.com/users/octocat/received_events',\n type: 'User',\n site_admin: false,\n },\n};\n\n```\n\n## `samples/sample_repo_list.js`\n\n```js\nmodule.exports = {\n id: 1296269,\n owner: {\n login: 'octocat',\n id: 1,\n avatar_url: 'https://github.com/images/error/octocat_happy.gif',\n gravatar_id: '',\n url: 'https://api.github.com/users/octocat',\n html_url: 'https://github.com/octocat',\n followers_url: 'https://api.github.com/users/octocat/followers',\n following_url:\n 'https://api.github.com/users/octocat/following{/other_user}',\n gists_url: 'https://api.github.com/users/octocat/gists{/gist_id}',\n starred_url: 'https://api.github.com/users/octocat/starred{/owner}{/repo}',\n subscriptions_url: 'https://api.github.com/users/octocat/subscriptions',\n organizations_url: 'https://api.github.com/users/octocat/orgs',\n repos_url: 'https://api.github.com/users/octocat/repos',\n events_url: 'https://api.github.com/users/octocat/events{/privacy}',\n received_events_url: 'https://api.github.com/users/octocat/received_events',\n type: 'User',\n site_admin: false,\n },\n name: 'Hello-World',\n full_name: 'octocat/Hello-World',\n description: 'This your first repo!',\n private: false,\n fork: false,\n url: 'https://api.github.com/repos/octocat/Hello-World',\n html_url: 'https://github.com/octocat/Hello-World',\n archive_url:\n 'https://api.github.com/repos/octocat/Hello-World/{archive_format}{/ref}',\n assignees_url:\n 'https://api.github.com/repos/octocat/Hello-World/assignees{/user}',\n blobs_url: 'https://api.github.com/repos/octocat/Hello-World/git/blobs{/sha}',\n branches_url:\n 'https://api.github.com/repos/octocat/Hello-World/branches{/branch}',\n clone_url: 'https://github.com/octocat/Hello-World.git',\n collaborators_url:\n 'https://api.github.com/repos/octocat/Hello-World/collaborators{/collaborator}',\n comments_url:\n 'https://api.github.com/repos/octocat/Hello-World/comments{/number}',\n commits_url: 'https://api.github.com/repos/octocat/Hello-World/commits{/sha}',\n compare_url:\n 'https://api.github.com/repos/octocat/Hello-World/compare/{base}...{head}',\n contents_url:\n 'https://api.github.com/repos/octocat/Hello-World/contents/{+path}',\n contributors_url:\n 'https://api.github.com/repos/octocat/Hello-World/contributors',\n deployments_url:\n 'https://api.github.com/repos/octocat/Hello-World/deployments',\n downloads_url: 'https://api.github.com/repos/octocat/Hello-World/downloads',\n events_url: 'https://api.github.com/repos/octocat/Hello-World/events',\n forks_url: 'https://api.github.com/repos/octocat/Hello-World/forks',\n git_commits_url:\n 'https://api.github.com/repos/octocat/Hello-World/git/commits{/sha}',\n git_refs_url:\n 'https://api.github.com/repos/octocat/Hello-World/git/refs{/sha}',\n git_tags_url:\n 'https://api.github.com/repos/octocat/Hello-World/git/tags{/sha}',\n git_url: 'git:github.com/octocat/Hello-World.git',\n hooks_url: 'https://api.github.com/repos/octocat/Hello-World/hooks',\n issue_comment_url:\n 'https://api.github.com/repos/octocat/Hello-World/issues/comments{/number}',\n issue_events_url:\n 'https://api.github.com/repos/octocat/Hello-World/issues/events{/number}',\n issues_url:\n 'https://api.github.com/repos/octocat/Hello-World/issues{/number}',\n keys_url: 'https://api.github.com/repos/octocat/Hello-World/keys{/key_id}',\n labels_url: 'https://api.github.com/repos/octocat/Hello-World/labels{/name}',\n languages_url: 'https://api.github.com/repos/octocat/Hello-World/languages',\n merges_url: 'https://api.github.com/repos/octocat/Hello-World/merges',\n milestones_url:\n 'https://api.github.com/repos/octocat/Hello-World/milestones{/number}',\n mirror_url: 'git:git.example.com/octocat/Hello-World',\n notifications_url:\n 'https://api.github.com/repos/octocat/Hello-World/notifications{?since,all,participating}',\n pulls_url: 'https://api.github.com/repos/octocat/Hello-World/pulls{/number}',\n releases_url:\n 'https://api.github.com/repos/octocat/Hello-World/releases{/id}',\n ssh_url: 'git@github.com:octocat/Hello-World.git',\n stargazers_url: 'https://api.github.com/repos/octocat/Hello-World/stargazers',\n statuses_url:\n 'https://api.github.com/repos/octocat/Hello-World/statuses/{sha}',\n subscribers_url:\n 'https://api.github.com/repos/octocat/Hello-World/subscribers',\n subscription_url:\n 'https://api.github.com/repos/octocat/Hello-World/subscription',\n svn_url: 'https://svn.github.com/octocat/Hello-World',\n tags_url: 'https://api.github.com/repos/octocat/Hello-World/tags',\n teams_url: 'https://api.github.com/repos/octocat/Hello-World/teams',\n trees_url: 'https://api.github.com/repos/octocat/Hello-World/git/trees{/sha}',\n homepage: 'https://github.com',\n language: null,\n forks_count: 9,\n stargazers_count: 80,\n watchers_count: 80,\n size: 108,\n default_branch: 'master',\n open_issues_count: 0,\n topics: ['octocat', 'atom', 'electron', 'API'],\n has_issues: true,\n has_wiki: true,\n has_pages: false,\n has_downloads: true,\n archived: false,\n pushed_at: '2011-01-26T19:06:43Z',\n created_at: '2011-01-26T19:01:12Z',\n updated_at: '2011-01-26T19:14:43Z',\n permissions: {\n admin: false,\n push: false,\n pull: true,\n },\n allow_rebase_merge: true,\n allow_squash_merge: true,\n allow_merge_commit: true,\n subscribers_count: 42,\n network_count: 0,\n license: {\n key: 'mit',\n name: 'MIT License',\n spdx_id: 'MIT',\n url: 'https://api.github.com/licenses/mit',\n html_url: 'https://choosealicense.com/licenses/mit/',\n },\n};\n\n```\n\n## `test/authentication.test.js`\n\n```js\n/* globals describe, it, expect, beforeAll, beforeEach, afterEach */\n\nconst zapier = require('zapier-platform-core');\nconst nock = require('nock');\n\nzapier.tools.env.inject(); // read from the .env file\n\nconst App = require('../index');\nconst appTester = zapier.createAppTester(App);\n\n// Only here so the tests out of the box.\n// You should create a `.env` file and populate it with the necessarily configuration\n// it should look like:\n/*\n CLIENT_ID=1234\n CLIENT_SECRET=asdf\n*/\n// then you can delete the following 2 lines\nprocess.env.CLIENT_ID = process.env.CLIENT_ID || '1234';\nprocess.env.CLIENT_SECRET = process.env.CLIENT_SECRET || 'asdf';\n\ndescribe('oauth2 app', () => {\n beforeAll(() => {\n // It's a good idea to store your Client ID and Secret in the environment rather than in code.\n if (!(process.env.CLIENT_ID && process.env.CLIENT_SECRET)) {\n throw new Error(\n `Before running the tests, make sure CLIENT_ID and CLIENT_SECRET are available in the environment.`,\n );\n }\n });\n\n afterEach(() => {\n nock.cleanAll();\n });\n\n it('generates an authorize URL', async () => {\n const bundle = {\n // In production, these will be generated by Zapier and set automatically\n inputData: {\n state: '4444',\n redirect_uri: 'https://zapier.com/',\n },\n environment: {\n CLIENT_ID: process.env.CLIENT_ID,\n CLIENT_SECRET: process.env.CLIENT_SECRET,\n },\n };\n\n const authorizeUrl = await appTester(\n App.authentication.oauth2Config.authorizeUrl,\n bundle,\n );\n\n expect(authorizeUrl).toBe(\n 'https://github.com/login/oauth/authorize?client_id=1234&state=4444&redirect_uri=https%3A%2F%2Fzapier.com%2F&response_type=code',\n );\n });\n});\n\ndescribe('getAccessToken', () => {\n beforeEach(async () => {\n nock('https://github.com/login/oauth')\n .post('/access_token')\n .reply(200, { access_token: 'someAccessToken' });\n });\n\n afterEach(() => {\n nock.cleanAll();\n });\n\n it('returns the expected tokens', async () => {\n const result = await appTester(\n App.authentication.oauth2Config.getAccessToken,\n );\n expect(result.access_token).toBe('someAccessToken');\n });\n});\n\ndescribe('testAuth', () => {\n const bundle = {\n // In production, these will be generated by Zapier and set automatically\n inputData: {\n state: '4444',\n redirect_uri: 'https://zapier.com/',\n },\n environment: {\n CLIENT_ID: process.env.CLIENT_ID,\n CLIENT_SECRET: process.env.CLIENT_SECRET,\n },\n };\n\n beforeEach(async () => {\n nock('https://api.github.com')\n .get('/user')\n .reply(200, {\n json: {\n login: 'myLogin',\n },\n });\n });\n\n afterEach(() => {\n nock.cleanAll();\n });\n\n it('returns the expected info', async () => {\n const result = await appTester(App.authentication.test, bundle);\n expect(result.data.json.login).toBe('myLogin');\n });\n});\n\n```\n\n## `triggers/issue.js`\n\n```js\nconst sample = require('../samples/sample_issue');\n\nconst triggerIssue = (z, bundle) => {\n const responsePromise = z.request({\n method: 'GET',\n url: `https://api.github.com/repos/${bundle.inputData.repo}/issues`,\n params: {\n filter: bundle.inputData.filter,\n state: bundle.inputData.state,\n sort: 'updated',\n direction: 'desc',\n },\n });\n return responsePromise.then((response) => response.data);\n};\n\nmodule.exports = {\n key: 'issue',\n noun: 'Issue',\n\n display: {\n label: 'New Issue',\n description: 'Triggers on a new issue.',\n },\n\n operation: {\n inputFields: [\n {\n key: 'repo',\n label: 'Repo',\n required: true,\n dynamic: 'repo.full_name.full_name',\n },\n {\n key: 'filter',\n required: false,\n label: 'Filter',\n choices: {\n assigned: 'assigned',\n created: 'created',\n mentioned: 'mentioned',\n subscribed: 'subscribed',\n all: 'all',\n },\n helpText: 'Default is \"assigned\"',\n },\n {\n key: 'state',\n required: false,\n label: 'State',\n choices: { open: 'open', closed: 'closed', all: 'all' },\n helpText: 'Default is \"open\"',\n },\n ],\n perform: triggerIssue,\n\n sample: sample,\n },\n};\n\n```\n\n## `triggers/repo.js`\n\n```js\nconst sample = require('../samples/sample_repo_list');\n\nconst triggerRepo = (z, bundle) => {\n const responsePromise = z.request({\n url: 'https://api.github.com/user/repos?per_page=100',\n });\n return responsePromise.then((response) => response.data);\n};\n\nmodule.exports = {\n key: 'repo',\n noun: 'Repo',\n\n display: {\n label: 'Get Repo',\n hidden: true,\n description:\n 'The only purpose of this trigger is to populate the dropdown list of repos in the UI, thus, it is hidden.',\n },\n\n operation: {\n inputFields: [],\n perform: triggerRepo,\n sample: sample,\n },\n};\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/github", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/github", "section": "templates", "tags": ["example", "template"], "related": [], "meta": {"files": ["index.js", "README.md", "package.json", "authentication.js", "creates/issue.js", "test/authentication.test.js", "triggers/issue.js", "triggers/repo.js", "samples/sample_repo_list.js", "samples/sample_issue.js"], "auth": null, "pattern": "example", "local": "repos/zapier-platform/example-apps/github"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:line-items", "kind": "template", "key": "line-items", "title": "Source template: line-items", "summary": "Full example-app source (n/a / line-items).", "body": "# example-app `line-items`\n\nAuth: `n/a` · Pattern: `line-items`\n\n## `README.md`\n\n```md\n# line-items\n\nThis Zapier integration project is generated by the `zapier-platform init` CLI command.\n\nThese are what you normally do next:\n\n```bash\n# Install dependencies\nnpm install --ignore-scripts # or you can use pnpm or yarn\n\n# Run tests\nzapier-platform test\n\n# Register the integration on Zapier if you haven't\nzapier-platform register \"App Title\"\n\n# Or you can link to an existing integration on Zapier\nzapier-platform link\n\n# Push it to Zapier\nzapier-platform push\n```\n\nThen, to add more features, you can use the `zapier-platform scaffold` command, for example:\n\n```bash\n# Add a trigger\nzapier-platform scaffold trigger contact\n\n# Add an action\nzapier-platform scaffold create contact\n``` \n\nFind out more on the latest docs: https://docs.zapier.com/platform\n\n# line-items\n\nAn example integration demonstrating line item support. Line items are fields\nwith a `children` property that represent structured, repeating data — like rows\nin a spreadsheet or items in an order.\n\n## Testing with `zapier-platform invoke`\n\n```bash\n# Non-interactive with JSON input\nzapier-platform invoke create order --non-interactive \\\n -i '{\"name\": \"My Order\", \"line_items\": [{\"product_name\": \"Pens\", \"quantity\": \"12\", \"price\": \"1.50\"}]}'\n\n# Interactive mode — use the line item editing UI\nzapier-platform invoke create order -i '{\"name\": \"My Order\"}'\n```\n\n```\n\n## `creates/order.js`\n\n```js\nconst perform = async (z, bundle) => {\n const response = await z.request({\n url: 'https://httpbin.zapier-tooling.com/post',\n method: 'POST',\n body: {\n name: bundle.inputData.name,\n line_items: bundle.inputData.line_items,\n },\n });\n\n return response.data;\n};\n\nmodule.exports = {\n key: 'order',\n noun: 'Order',\n display: {\n label: 'Create Order',\n description: 'Creates a new order with line items.',\n },\n operation: {\n inputFields: [\n { key: 'name', required: true, type: 'string', label: 'Order Name' },\n {\n key: 'line_items',\n label: 'Line Items',\n children: [\n {\n key: 'product_name',\n type: 'string',\n label: 'Product Name',\n required: true,\n },\n {\n key: 'quantity',\n type: 'integer',\n label: 'Quantity',\n required: true,\n },\n { key: 'price', type: 'number', label: 'Unit Price' },\n ],\n },\n ],\n perform,\n sample: {\n id: 1,\n name: 'Stationery Order',\n line_items: [\n { product_name: 'Pens', quantity: 12, price: 1.5 },\n { product_name: 'Notebooks', quantity: 3, price: 8.99 },\n ],\n },\n outputFields: [\n { key: 'id', label: 'ID' },\n { key: 'name', label: 'Order Name' },\n {\n key: 'line_items',\n label: 'Line Items',\n children: [\n { key: 'product_name', label: 'Product Name' },\n { key: 'quantity', label: 'Quantity' },\n { key: 'price', label: 'Unit Price' },\n ],\n },\n ],\n },\n};\n\n```\n\n## `index.js`\n\n```js\nconst order = require('./creates/order');\n\nconst App = {\n version: require('./package.json').version,\n platformVersion: require('zapier-platform-core').version,\n\n creates: {\n [order.key]: order,\n },\n};\n\nmodule.exports = App;\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"line-items\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"scripts\": {\n \"test\": \"jest --testTimeout 10000\"\n },\n \"dependencies\": {\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"jest\": \"^29.6.0\"\n },\n \"private\": true,\n \"main\": \"index.js\"\n}\n\n```\n\n## `test/creates.test.js`\n\n```js\n/* globals describe, expect, test */\n\nconst zapier = require('zapier-platform-core');\n\nconst App = require('../index');\nconst appTester = zapier.createAppTester(App);\nzapier.tools.env.inject();\n\ndescribe('creates', () => {\n test('create order with line items', async () => {\n const bundle = {\n inputData: {\n name: 'Test Order',\n line_items: [\n { product_name: 'Pens', quantity: 12, price: 1.5 },\n { product_name: 'Notebooks', quantity: 3, price: 8.99 },\n ],\n },\n };\n const result = await appTester(\n App.creates.order.operation.perform,\n bundle,\n );\n const body = JSON.parse(result.data);\n expect(body.name).toBe('Test Order');\n expect(body.line_items).toHaveLength(2);\n expect(body.line_items[0].product_name).toBe('Pens');\n expect(body.line_items[1].quantity).toBe(3);\n });\n});\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/line-items", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/line-items", "section": "templates", "tags": ["example", "line-items", "template"], "related": [], "meta": {"files": ["index.js", "README.md", "package.json", "creates/order.js", "test/creates.test.js"], "auth": null, "pattern": "line-items", "local": "repos/zapier-platform/example-apps/line-items"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:middleware", "kind": "template", "key": "middleware", "title": "Source template: middleware", "summary": "Full example-app source (n/a / middleware).", "body": "# example-app `middleware`\n\nAuth: `n/a` · Pattern: `middleware`\n\n## `README.md`\n\n```md\n# HTTP Middleware Example App For Zapier Platform\n\n[![Build Status](https://travis-ci.org/zapier/zapier-platform-example-app-middleware.svg?branch=master)](https://travis-ci.org/zapier/zapier-platform-example-app-middleware)\n\nA simple app that demonstrates the use of HTTP before and after middleware.\n\n> We recommend using the zapier-platform-cli and `zapier-platform init .`  to create an app - youll be presented with a list of currently available templates to start with.\n\n```\n\n## `index.js`\n\n```js\nconst _ = require('lodash');\n\nconst recipe = require('./triggers/recipe');\nconst movie = require('./triggers/movie');\n\n// HTTP before middleware that adds sorting query params.\n// We want *every* request to our API to be sorted in reverse chronological order.\n// Applying this middleware guarantees this.\nconst addSortingParams = (request /*, z */) => {\n request.params = _.extend({}, request.params, {\n _sort: 'id',\n _order: 'desc',\n });\n return request;\n};\n\n// HTTP after middleware that checks for errors in the response.\nconst handleErrors = (response, z) => {\n // Prevent `throwForStatus` from throwing for a certain status.\n if (response.status === 456) {\n response.skipThrowForStatus = true;\n }\n\n // Throw an error that `throwForStatus` wouldn't throw (correctly) for.\n else if (response.status === 200 && response.data.success === false) {\n throw new z.errors.Error(response.data.message, response.data.code);\n }\n\n return response;\n};\n\n// Now we can roll up all our behaviors in an App.\nconst App = {\n // This is just shorthand to reference the installed dependencies you have. Zapier will\n // need to know these before we can upload\n version: require('./package.json').version,\n platformVersion: require('zapier-platform-core').version,\n\n beforeRequest: [\n // add our before middlewares\n addSortingParams,\n ],\n\n afterResponse: [\n // add our after middlewares\n handleErrors,\n ],\n\n resources: {},\n\n // If you want your trigger to show up, you better include it here!\n triggers: {\n [recipe.key]: recipe,\n [movie.key]: movie,\n },\n\n // If you want your searches to show up, you better include it here!\n searches: {},\n\n // If you want your creates to show up, you better include it here!\n creates: {},\n};\n\n// Finally, export the app.\nmodule.exports = App;\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"zapier-platform-example-app-middleware\",\n \"version\": \"1.0.0\",\n \"description\": \"An example app for the Zapier platform.\",\n \"repository\": \"zapier/zapier-platform-example-app-middleware\",\n \"homepage\": \"https://zapier.com/\",\n \"author\": \"Bryan Helmig <bryan@zapier.com>\",\n \"license\": \"BSD-3-Clause\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"mocha --recursive\"\n },\n \"engines\": {\n \"node\": \">=8.10.0\",\n \"npm\": \">=5.6.0\"\n },\n \"dependencies\": {\n \"lodash\": \"4.18.1\",\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"mocha\": \"^5.2.0\",\n \"should\": \"^13.2.0\"\n },\n \"private\": true\n}\n\n```\n\n## `test/triggers.js`\n\n```js\n/* globals describe, it */\n\nrequire('should');\n\nconst zapier = require('zapier-platform-core');\n\nconst App = require('../index');\nconst appTester = zapier.createAppTester(App);\n\ndescribe('triggers', () => {\n describe('new recipe trigger', () => {\n it('should load recipes', (done) => {\n appTester(App.triggers.recipe.operation.perform)\n .then((results) => {\n results.should.be.an.Array();\n results.length.should.be.above(1);\n\n // Make sure the results are ordered by id desc\n let i = 0;\n while (i < results.length - 1) {\n const cur = results[i];\n const nxt = results[i + 1];\n cur.id.should.be.aboveOrEqual(nxt.id);\n i++;\n }\n\n done();\n })\n .catch(done);\n });\n });\n\n describe('new movie trigger', () => {\n it('should load movies', (done) => {\n appTester(App.triggers.movie.operation.perform)\n .then((results) => {\n results.should.be.an.Array();\n results.length.should.be.above(1);\n\n // Make sure the results are ordered by id desc\n let i = 0;\n while (i < results.length - 1) {\n const cur = results[i];\n const nxt = results[i + 1];\n cur.id.should.be.aboveOrEqual(nxt.id);\n i++;\n }\n\n done();\n })\n .catch(done);\n });\n });\n});\n\n```\n\n## `triggers/movie.js`\n\n```js\nmodule.exports = {\n key: 'movie',\n\n noun: 'Movie',\n display: {\n label: 'New Movie',\n description: 'Trigger when a new movie is added.',\n },\n\n operation: {\n perform: {\n url: 'https://auth-json-server.zapier-staging.com/movies',\n params: {\n // Just a demo, this is NOT how you normally do authentication.\n // Refer to https://docs.zapier.com/platform/reference/cli-docs#authentication\n api_key: 'secret',\n },\n },\n\n // In cases where Zapier needs to show an example record to the user, but we are unable to get a live example\n // from the API, Zapier will fallback to this hard-coded sample. It should reflect the data structure of\n // returned records, and have obviously dummy values that we can show to any user.\n sample: {\n id: 1,\n releaseDate: 1472069465,\n title: 'Test Title',\n genre: 'Sci-Fi',\n },\n\n // If the resource can have fields that are custom on a per-user basis, define a function to fetch the custom\n // field definitions. The result will be used to augment the sample.\n // outputFields: () => { return []; }\n // Alternatively, a static field definition should be provided, to specify labels for the fields\n outputFields: [\n { key: 'id', label: 'ID' },\n { key: 'releaseDate', label: 'Release Date' },\n { key: 'title', label: 'Title' },\n { key: 'genre', label: 'Genre' },\n ],\n },\n};\n\n```\n\n## `triggers/recipe.js`\n\n```js\nmodule.exports = {\n key: 'recipe',\n\n // You'll want to provide some helpful display labels and descriptions\n // for users. Zapier will put them into the UX.\n noun: 'Recipe',\n display: {\n label: 'New Recipe',\n description: 'Trigger when a new recipe is added.',\n },\n\n // `operation` is where we make the call to your API\n operation: {\n perform: {\n url: 'https://auth-json-server.zapier-staging.com/recipes',\n params: {\n // Just a demo, this is NOT how you normally do authentication.\n // Refer to https://docs.zapier.com/platform/reference/cli-docs#authentication\n api_key: 'secret',\n },\n },\n\n // In cases where Zapier needs to show an example record to the user, but we are unable to get a live example\n // from the API, Zapier will fallback to this hard-coded sample. It should reflect the data structure of\n // returned records, and have obviously dummy values that we can show to any user.\n sample: {\n id: 1,\n createdAt: 1472069465,\n name: 'Best Spagetti Ever',\n authorId: 1,\n directions: '1. Boil Noodles\\n2.Serve with sauce',\n style: 'italian',\n },\n\n // If the resource can have fields that are custom on a per-user basis, define a function to fetch the custom\n // field definitions. The result will be used to augment the sample.\n // outputFields: () => { return []; }\n // Alternatively, a static field definition should be provided, to specify labels for the fields\n outputFields: [\n { key: 'id', label: 'ID' },\n { key: 'createdAt', label: 'Created At' },\n { key: 'name', label: 'Name' },\n { key: 'directions', label: 'Directions' },\n { key: 'authorId', label: 'Author ID' },\n { key: 'style', label: 'Style' },\n ],\n },\n};\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/middleware", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/middleware", "section": "templates", "tags": ["example", "middleware", "template"], "related": [], "meta": {"files": ["index.js", "README.md", "package.json", "test/triggers.js", "triggers/recipe.js", "triggers/movie.js"], "auth": null, "pattern": "middleware", "local": "repos/zapier-platform/example-apps/middleware"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:minimal", "kind": "template", "key": "minimal", "title": "Source template: minimal", "summary": "Full example-app source (n/a / example).", "body": "# example-app `minimal`\n\nAuth: `n/a` · Pattern: `example`\n\n## `README.md`\n\n```md\n# minimal\n\nThis Zapier integration project is generated by the `zapier-platform init` CLI command.\n\nThese are what you normally do next:\n\n```bash\n# Install dependencies\nnpm install # or you can use yarn\n\n# Run tests\nzapier-platform test\n\n# Register the integration on Zapier if you haven't\nzapier-platform register \"App Title\"\n\n# Or you can link to an existing integration on Zapier\nzapier-platform link\n\n# Push it to Zapier\nzapier-platform push\n```\n\nFind out more on the latest docs: https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md.\n\n```\n\n## `index.js`\n\n```js\nmodule.exports = {\n // This is just shorthand to reference the installed dependencies you have.\n // Zapier will need to know these before we can upload.\n version: require('./package.json').version,\n platformVersion: require('zapier-platform-core').version,\n\n // If you want your trigger to show up, you better include it here!\n triggers: {},\n\n // If you want your searches to show up, you better include it here!\n searches: {},\n\n // If you want your creates to show up, you better include it here!\n creates: {},\n\n resources: {},\n};\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"minimal\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"jest --testTimeout 10000\"\n },\n \"dependencies\": {\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"jest\": \"^25.5.3\"\n },\n \"private\": true\n}\n\n```\n\n## `test/example.test.js`\n\n```js\n/* globals describe, it, expect */\n\ndescribe('addition ', () => {\n it('should work', () => {\n expect(1 + 1).toEqual(2);\n });\n});\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/minimal", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/minimal", "section": "templates", "tags": ["example", "template"], "related": ["zapier-platform init --template minimal"], "meta": {"files": ["index.js", "README.md", "package.json", "test/example.test.js"], "auth": null, "pattern": "example", "local": "repos/zapier-platform/example-apps/minimal"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:minimal-esm", "kind": "template", "key": "minimal-esm", "title": "Source template: minimal-esm", "summary": "Full example-app source (n/a / example).", "body": "# example-app `minimal-esm`\n\nAuth: `n/a` · Pattern: `example`\n\n## `README.md`\n\n```md\n# minimal-esm\n\nThis Zapier integration project is generated by the `zapier-platform init` CLI command.\n\nThese are what you normally do next:\n\n```bash\n# Install dependencies\nnpm install # or you can use yarn\n\n# Run tests\nzapier-platform test\n\n# Register the integration on Zapier if you haven't\nzapier-platform register \"App Title\"\n\n# Or you can link to an existing integration on Zapier\nzapier-platform link\n\n# Push it to Zapier\nzapier-platform push\n```\n\nFind out more on the latest docs: https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md.\n\n```\n\n## `index.js`\n\n```js\nimport packageJson from './package.json' with { type: 'json' };\nimport zapier from 'zapier-platform-core';\n\nexport default {\n // This is just shorthand to reference the installed dependencies you have.\n // Zapier will need to know these before we can upload.\n version: packageJson.version,\n platformVersion: zapier.version,\n\n // If you want your trigger to show up, you better include it here!\n triggers: {},\n\n // If you want your searches to show up, you better include it here!\n searches: {},\n\n // If you want your creates to show up, you better include it here!\n creates: {},\n\n resources: {},\n};\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"minimal-esm\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"scripts\": {\n \"test\": \"jest --testTimeout 10000\"\n },\n \"dependencies\": {\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"jest\": \"^29.6.0\"\n },\n \"private\": true,\n \"exports\": \"./index.js\",\n \"type\": \"module\"\n}\n\n```\n\n## `test/example.test.js`\n\n```js\n/* globals describe, it, expect */\n\ndescribe('addition ', () => {\n it('should work', () => {\n expect(1 + 1).toEqual(2);\n });\n});\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/minimal-esm", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/minimal-esm", "section": "templates", "tags": ["example", "template"], "related": [], "meta": {"files": ["index.js", "README.md", "package.json", "test/example.test.js"], "auth": null, "pattern": "example", "local": "repos/zapier-platform/example-apps/minimal-esm"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:oauth1-trello", "kind": "template", "key": "oauth1-trello", "title": "Source template: oauth1-trello", "summary": "Full example-app source (oauth1 / example).", "body": "# example-app `oauth1-trello`\n\nAuth: `oauth1` · Pattern: `example`\n\n## `README.md`\n\n```md\n# oauth1-trello\n\nThis Zapier integration project is generated by the `zapier-platform init` CLI command.\n\nThese are what you normally do next:\n\n```bash\n# Install dependencies\nnpm install # or you can use yarn\n\n# Run tests\nzapier-platform test\n\n# Register the integration on Zapier if you haven't\nzapier-platform register \"App Title\"\n\n# Or you can link to an existing integration on Zapier\nzapier-platform link\n\n# Push it to Zapier\nzapier-platform push\n```\n\nThen, to add more features, you can use the `zapier-platform scaffold` command, for example:\n\n```bash\n# Add a trigger\nzapier-platform scaffold trigger contact\n\n# Add an action\nzapier-platform scaffold create contact\n``` \n\nFind out more on the latest docs: https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md.\n\n```\n\n## `authentication.js`\n\n```js\n'use strict';\n\nconst querystring = require('querystring');\n\nconst REQUEST_TOKEN_URL = 'https://trello.com/1/OAuthGetRequestToken';\nconst ACCESS_TOKEN_URL = 'https://trello.com/1/OAuthGetAccessToken';\nconst AUTHORIZE_URL = 'https://trello.com/1/OAuthAuthorizeToken';\n\nconst getRequestToken = async (z, bundle) => {\n const response = await z.request({\n url: REQUEST_TOKEN_URL,\n method: 'POST',\n auth: {\n oauth_consumer_key: process.env.CLIENT_ID,\n oauth_consumer_secret: process.env.CLIENT_SECRET,\n oauth_signature_method: 'HMAC-SHA1',\n oauth_callback: bundle.inputData.redirect_uri,\n\n // oauth_version: '1.0' // sometimes required\n },\n });\n return querystring.parse(response.content);\n};\n\nconst getAccessToken = async (z, bundle) => {\n const response = await z.request({\n url: ACCESS_TOKEN_URL,\n method: 'POST',\n auth: {\n oauth_consumer_key: process.env.CLIENT_ID,\n oauth_consumer_secret: process.env.CLIENT_SECRET,\n oauth_token: bundle.inputData.oauth_token,\n oauth_token_secret: bundle.inputData.oauth_token_secret,\n oauth_verifier: bundle.inputData.oauth_verifier,\n },\n });\n return querystring.parse(response.content);\n};\n\n// You want to make a request to an endpoint that is either specifically designed\n// to test auth, or one that every user will have access to. eg: `/me`.\n// By returning the entire request object, you have access to the request and\n// response data for testing purposes. Your connection label can access any data\n// from the returned response using the `json.` prefix. eg: `{{json.username}}`.\nconst test = (z, bundle) =>\n z.request({ url: 'https://api.trello.com/1/members/me/' });\n\nmodule.exports = {\n // OAuth1 is an older form of OAuth\n type: 'oauth1',\n oauth1Config: {\n // We have to define getRequestToken and getAccessToken functions to explicitly\n // parse the response like it has a form body here, since Trello responds\n // 'text/plain' for the Content-Type header\n getRequestToken,\n getAccessToken,\n authorizeUrl: {\n url: AUTHORIZE_URL,\n params: {\n oauth_token: '{{bundle.inputData.oauth_token}}',\n name: 'Zapier/Trello OAuth1 Test',\n },\n },\n },\n\n // Define any input app's auth requires here. The user will be prompted to enter\n // this info when they connect their account.\n fields: [],\n\n // The test method allows Zapier to verify that the credentials a user provides\n // are valid. We'll execute this method whenever a user connects their account for\n // the first time.\n test,\n\n // This template string can access all the data returned from the auth test. If\n // you return the test object, you'll access the returned data with a label like\n // `{{json.X}}`. If you return `response.data` from your test, then your label can\n // be `{{X}}`. This can also be a function that returns a label. That function has\n // the standard args `(z, bundle)` and data returned from the test can be accessed\n // in `bundle.inputData.X`.\n connectionLabel: '{{username}}',\n};\n\n```\n\n## `index.js`\n\n```js\nconst authentication = require('./authentication');\nconst { befores = [], afters = [] } = require('./middleware');\n\nmodule.exports = {\n // This is just shorthand to reference the installed dependencies you have.\n // Zapier will need to know these before we can upload.\n version: require('./package.json').version,\n platformVersion: require('zapier-platform-core').version,\n\n authentication,\n\n beforeRequest: [...befores],\n\n afterResponse: [...afters],\n\n // If you want your trigger to show up, you better include it here!\n triggers: {},\n\n // If you want your searches to show up, you better include it here!\n searches: {},\n\n // If you want your creates to show up, you better include it here!\n creates: {},\n\n resources: {},\n};\n\n```\n\n## `middleware.js`\n\n```js\n'use strict';\n\n// This function runs before every outbound request. You can have as many as you\n// need. They'll need to each be registered in your index.js file.\nconst includeAccessToken = (request, z, bundle) => {\n if (\n bundle.authData &&\n bundle.authData.oauth_token &&\n bundle.authData.oauth_token_secret\n ) {\n // Put your OAuth1 credentials in `req.auth`, Zapier will sign the request for\n // you.\n request.auth = {\n oauth_consumer_key: process.env.CLIENT_ID,\n oauth_consumer_secret: process.env.CLIENT_SECRET,\n oauth_token: bundle.authData.oauth_token,\n oauth_token_secret: bundle.authData.oauth_token_secret,\n\n // oauth_version: '1.0', // sometimes required\n ...(request.auth || {}),\n };\n }\n\n return request;\n};\n\nmodule.exports = { befores: [includeAccessToken], afters: [] };\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"oauth1-trello\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"jest --testTimeout 10000\"\n },\n \"dependencies\": {\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"jest\": \"^29.6.0\"\n },\n \"private\": true\n}\n\n```\n\n## `test/authentication.test.js`\n\n```js\n/* globals describe, it, expect, beforeAll */\n\nconst zapier = require('zapier-platform-core');\n\nzapier.tools.env.inject(); // read from the .env file\n\nconst App = require('../index');\nconst appTester = zapier.createAppTester(App);\n\n// You should create a `.env` file and populate it with your actual Trello\n// client ID and secret (called \"API Key\" and \"API Secret\" by Trello), which you\n// can find on https://trello.com/app-key.\n// The `.env` file should look like\n/*\n CLIENT_ID=<trello_api_key>\n CLIENT_SECRET=<trello_api_secret>\n*/\n// then you can delete the following 2 lines\nprocess.env.CLIENT_ID = process.env.CLIENT_ID || '<trello_api_key>';\nprocess.env.CLIENT_SECRET = process.env.CLIENT_SECRET || '<trello_api_secret>';\n\ndescribe('oauth1 app', () => {\n beforeAll(() => {\n // It's a good idea to store your Client ID and Secret in the environment rather than in code.\n if (!(process.env.CLIENT_ID && process.env.CLIENT_SECRET)) {\n throw new Error(\n `Before running the tests, make sure CLIENT_ID and CLIENT_SECRET are available in the environment.`,\n );\n }\n });\n\n it('fetch a request token', async () => {\n const bundle = {\n inputData: {\n // You should add your redirect URI to https://trello.com/app-key\n redirect_uri: 'https://zapier.com',\n },\n };\n const tokens = await appTester(\n App.authentication.oauth1Config.getRequestToken,\n bundle,\n );\n expect(tokens).toHaveProperty('oauth_token');\n expect(tokens).toHaveProperty('oauth_token_secret');\n });\n\n it('generates an authorize URL', async () => {\n const bundle = {\n // In production, these will be generated by Zapier and set automatically\n inputData: {\n oauth_token: '4444',\n redirect_uri: 'https://zapier.com/',\n },\n };\n\n const authorizeUrl = await appTester(\n App.authentication.oauth1Config.authorizeUrl,\n bundle,\n );\n\n expect(authorizeUrl).toBe(\n 'https://trello.com/1/OAuthAuthorizeToken?oauth_token=4444&name=Zapier%2FTrello%20OAuth1%20Test',\n );\n });\n});\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/oauth1-trello", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/oauth1-trello", "section": "templates", "tags": ["example", "oauth1", "template"], "related": ["zapier-platform init --template oauth1-trello"], "meta": {"files": ["index.js", "README.md", "package.json", "middleware.js", "authentication.js", "test/authentication.test.js"], "auth": "oauth1", "pattern": "example", "local": "repos/zapier-platform/example-apps/oauth1-trello"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:oauth1-trello-typescript", "kind": "template", "key": "oauth1-trello-typescript", "title": "Source template: oauth1-trello-typescript", "summary": "Full example-app source (oauth1 / example).", "body": "# example-app `oauth1-trello-typescript`\n\nAuth: `oauth1` · Pattern: `example`\n\n## `README.md`\n\n```md\n# oauth1-trello-typescript\n\nThis Zapier integration project is generated by the `zapier-platform init` CLI command.\n\nThese are what you normally do next:\n\n```bash\n# Install dependencies\nnpm install # or you can use yarn\n\n# Run tests\nzapier-platform test\n\n# Register the integration on Zapier if you haven't\nzapier-platform register \"App Title\"\n\n# Or you can link to an existing integration on Zapier\nzapier-platform link\n\n# Push it to Zapier\nzapier-platform push\n```\n\nThen, to add more features, you can use the `zapier-platform scaffold` command, for example:\n\n```bash\n# Add a trigger\nzapier-platform scaffold trigger contact\n\n# Add an action\nzapier-platform scaffold create contact\n``` \n\nFind out more on the latest docs: https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md.\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"oauth1-trello-typescript\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"scripts\": {\n \"test\": \"npm run build && vitest --run\",\n \"clean\": \"rimraf ./dist ./build\",\n \"build\": \"npm run clean && tsc\",\n \"_zapier-build\": \"npm run build\"\n },\n \"dependencies\": {\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"rimraf\": \"^5.0.10\",\n \"typescript\": \"5.6.2\",\n \"vitest\": \"^2.1.2\"\n },\n \"private\": true,\n \"exports\": \"./dist/index.js\",\n \"type\": \"module\"\n}\n\n```\n\n## `src/authentication.ts`\n\n```ts\nimport type { ZObject, Bundle, Authentication } from 'zapier-platform-core';\n\nconst querystring = require('querystring');\n\nconst REQUEST_TOKEN_URL = 'https://trello.com/1/OAuthGetRequestToken';\nconst ACCESS_TOKEN_URL = 'https://trello.com/1/OAuthGetAccessToken';\nconst AUTHORIZE_URL = 'https://trello.com/1/OAuthAuthorizeToken';\n\nconst getRequestToken = async (z: ZObject, bundle: Bundle) => {\n const response = await z.request({\n url: REQUEST_TOKEN_URL,\n method: 'POST',\n auth: {\n oauth_consumer_key: process.env.CLIENT_ID,\n oauth_consumer_secret: process.env.CLIENT_SECRET,\n oauth_signature_method: 'HMAC-SHA1',\n oauth_callback: bundle.inputData.redirect_uri,\n\n // oauth_version: '1.0' // sometimes required\n },\n });\n return querystring.parse(response.content);\n};\n\nconst getAccessToken = async (z: ZObject, bundle: Bundle) => {\n const response = await z.request({\n url: ACCESS_TOKEN_URL,\n method: 'POST',\n auth: {\n oauth_consumer_key: process.env.CLIENT_ID,\n oauth_consumer_secret: process.env.CLIENT_SECRET,\n oauth_token: bundle.inputData.oauth_token,\n oauth_token_secret: bundle.inputData.oauth_token_secret,\n oauth_verifier: bundle.inputData.oauth_verifier,\n },\n });\n return querystring.parse(response.content);\n};\n\n// You want to make a request to an endpoint that is either specifically designed\n// to test auth, or one that every user will have access to. eg: `/me`.\n// By returning the entire request object, you have access to the request and\n// response data for testing purposes. Your connection label can access any data\n// from the returned response using the `json.` prefix. eg: `{{json.username}}`.\nconst test = (z: ZObject, bundle: Bundle) =>\n z.request({ url: 'https://api.trello.com/1/members/me/' });\n\nexport default {\n // OAuth1 is an older form of OAuth\n type: 'oauth1',\n oauth1Config: {\n // We have to define getRequestToken and getAccessToken functions to explicitly\n // parse the response like it has a form body here, since Trello responds\n // 'text/plain' for the Content-Type header\n getRequestToken,\n getAccessToken,\n authorizeUrl: {\n url: AUTHORIZE_URL,\n params: {\n oauth_token: '{{bundle.inputData.oauth_token}}',\n name: 'Zapier/Trello OAuth1 Test',\n },\n },\n },\n\n // Define any input app's auth requires here. The user will be prompted to enter\n // this info when they connect their account.\n fields: [],\n\n // The test method allows Zapier to verify that the credentials a user provides\n // are valid. We'll execute this method whenever a user connects their account for\n // the first time.\n test,\n\n // This template string can access all the data returned from the auth test. If\n // you return the test object, you'll access the returned data with a label like\n // `{{json.X}}`. If you return `response.data` from your test, then your label can\n // be `{{X}}`. This can also be a function that returns a label. That function has\n // the standard args `(z: ZObject, bundle: Bundle)` and data returned from the\n // test can be accessed in `bundle.inputData.X`.\n connectionLabel: '{{username}}',\n} satisfies Authentication;\n\n```\n\n## `src/index.ts`\n\n```ts\nimport zapier, { defineApp } from 'zapier-platform-core';\n\nimport packageJson from '../package.json' with { type: 'json' };\n\nimport authentication from './authentication.js';\nimport { befores, afters } from './middleware.js';\n\nexport default defineApp({\n version: packageJson.version,\n platformVersion: zapier.version,\n\n authentication,\n beforeRequest: [...befores],\n afterResponse: [...afters],\n\n // Add your triggers here for them to show up!\n triggers: {},\n\n // Add your creates here for them to show up!\n creates: {},\n});\n\n```\n\n## `src/middleware.ts`\n\n```ts\nimport type { ZObject, Bundle, Authentication } from 'zapier-platform-core';\n\n// This function runs before every outbound request. You can have as many as you\n// need. They'll need to each be registered in your index.js file.\nconst includeAccessToken = (request, z: ZObject, bundle: Bundle) => {\n if (\n bundle.authData &&\n bundle.authData.oauth_token &&\n bundle.authData.oauth_token_secret\n ) {\n // Put your OAuth1 credentials in `req.auth`, Zapier will sign the request for\n // you.\n request.auth = {\n oauth_consumer_key: process.env.CLIENT_ID,\n oauth_consumer_secret: process.env.CLIENT_SECRET,\n oauth_token: bundle.authData.oauth_token,\n oauth_token_secret: bundle.authData.oauth_token_secret,\n\n // oauth_version: '1.0', // sometimes required\n ...(request.auth || {}),\n };\n }\n\n return request;\n};\n\nexport const befores = [includeAccessToken];\n\nexport const afters = [];\n\n```\n\n## `src/test/authentication.test.ts`\n\n```ts\nimport { describe, expect, it, beforeAll } from 'vitest';\nimport zapier from 'zapier-platform-core';\n\nimport App from '../index.js';\nconst appTester = zapier.createAppTester(App);\n\n// Only defining the env vars here so the tests out of the box.\n// You should create a `.env` file and populate it with your actual Trello\n// client ID and secret (called \"API Key\" and \"API Secret\" by Trello), which you\n// can find on https://trello.com/app-key.\n// The `.env` file should look like\n/*\n CLIENT_ID=<trello_api_key>\n CLIENT_SECRET=<trello_api_secret>\n*/\n// then you can delete the following 2 lines\nprocess.env.CLIENT_ID = process.env.CLIENT_ID || '<trello_api_key>';\nprocess.env.CLIENT_SECRET = process.env.CLIENT_SECRET || '<trello_api_secret>';\n\ndescribe('oauth1 app', () => {\n beforeAll(() => {\n // It's a good idea to store your Client ID and Secret in the environment rather than in code.\n if (!(process.env.CLIENT_ID && process.env.CLIENT_SECRET)) {\n throw new Error(\n `Before running the tests, make sure CLIENT_ID and CLIENT_SECRET are available in the environment.`,\n );\n }\n });\n\n it('fetch a request token', async () => {\n const bundle = {\n inputData: {\n // You should add your redirect URI to https://trello.com/app-key\n redirect_uri: 'https://zapier.com',\n },\n };\n const tokens = await appTester(\n App.authentication.oauth1Config.getRequestToken,\n bundle,\n );\n expect(tokens).toHaveProperty('oauth_token');\n expect(tokens).toHaveProperty('oauth_token_secret');\n });\n\n it('generates an authorize URL', async () => {\n const bundle = {\n // In production, these will be generated by Zapier and set automatically\n inputData: {\n oauth_token: '4444',\n redirect_uri: 'https://zapier.com/',\n },\n };\n\n const authorizeUrl = await appTester(\n App.authentication.oauth1Config.authorizeUrl,\n bundle,\n );\n\n expect(authorizeUrl).toBe(\n 'https://trello.com/1/OAuthAuthorizeToken?oauth_token=4444&name=Zapier%2FTrello%20OAuth1%20Test',\n );\n });\n});\n\n```\n\n## `tsconfig.json`\n\n```json\n{\n \"compilerOptions\": {\n \"target\": \"ESNext\",\n \"module\": \"NodeNext\",\n \"moduleResolution\": \"NodeNext\",\n \"resolveJsonModule\": true,\n \"esModuleInterop\": true,\n \"noUncheckedIndexedAccess\": true,\n \"isolatedModules\": true,\n \"noImplicitAny\": false,\n \"skipLibCheck\": true,\n \"outDir\": \"./dist\",\n \"rootDir\": \"./src\",\n \"strict\": true\n },\n \"include\": [\"./src/**/*.ts\"],\n \"exclude\": [\"./**/*.test.ts\"]\n}\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/oauth1-trello-typescript", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/oauth1-trello-typescript", "section": "templates", "tags": ["example", "oauth1", "template"], "related": ["zapier-platform init --template oauth1-trello-typescript"], "meta": {"files": ["README.md", "package.json", "tsconfig.json", "src/middleware.ts", "src/authentication.ts", "src/index.ts", "src/test/authentication.test.ts"], "auth": "oauth1", "pattern": "example", "local": "repos/zapier-platform/example-apps/oauth1-trello-typescript"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:oauth1-tumblr", "kind": "template", "key": "oauth1-tumblr", "title": "Source template: oauth1-tumblr", "summary": "Full example-app source (oauth1 / example).", "body": "# example-app `oauth1-tumblr`\n\nAuth: `oauth1` · Pattern: `example`\n\n## `README.md`\n\n```md\n# \"OAuth1\" Tumblr Example App For Zapier Platform\n\nRequires CLI **7.5.0** and above! A barebones app that has OAuth1 setup, using Tumblr for example.\n\n> We recommend using the zapier-platform-cli and `zapier-platform init . --template=oauth1-tumblr` to create an app.\n\n```\n\n## `authentication.js`\n\n```js\nconst _ = require('lodash');\n\nconst REQUEST_TOKEN_URL = 'https://www.tumblr.com/oauth/request_token';\nconst ACCESS_TOKEN_URL = 'https://www.tumblr.com/oauth/access_token';\nconst AUTHORIZE_URL = 'https://www.tumblr.com/oauth/authorize';\n\nconst getConnectionLabel = (z, bundle) => {\n try {\n return bundle.inputData.response.user.name;\n } catch (err) {\n return '';\n }\n};\n\nconst config = {\n type: 'oauth1',\n oauth1Config: {\n getRequestToken: {\n url: REQUEST_TOKEN_URL,\n method: 'POST',\n auth: {\n oauth_consumer_key: '{{process.env.CLIENT_ID}}',\n oauth_consumer_secret: '{{process.env.CLIENT_SECRET}}',\n oauth_signature_method: 'HMAC-SHA1',\n oauth_callback: '{{bundle.inputData.redirect_uri}}',\n },\n },\n authorizeUrl: {\n url: AUTHORIZE_URL,\n params: {\n oauth_token: '{{bundle.inputData.oauth_token}}',\n },\n },\n getAccessToken: {\n url: ACCESS_TOKEN_URL,\n method: 'POST',\n auth: {\n oauth_consumer_key: '{{process.env.CLIENT_ID}}',\n oauth_consumer_secret: '{{process.env.CLIENT_SECRET}}',\n oauth_token: '{{bundle.inputData.oauth_token}}',\n oauth_token_secret: '{{bundle.inputData.oauth_token_secret}}',\n oauth_verifier: '{{bundle.inputData.oauth_verifier}}',\n },\n },\n },\n test: {\n url: 'https://api.tumblr.com/v2/user/info',\n },\n connectionLabel: getConnectionLabel,\n};\n\n// A middleware that is run before z.request() actually makes the request. Here we're\n// adding necessary OAuth1 parameters to `auth` property of the request object.\nconst includeAccessToken = (req, z, bundle) => {\n if (\n bundle.authData &&\n bundle.authData.oauth_token &&\n bundle.authData.oauth_token_secret\n ) {\n // Just put your OAuth1 credentials in req.auth, Zapier will sign the request for\n // you.\n req.auth = req.auth || {};\n _.defaults(req.auth, {\n oauth_consumer_key: process.env.CLIENT_ID,\n oauth_consumer_secret: process.env.CLIENT_SECRET,\n oauth_token: bundle.authData.oauth_token,\n oauth_token_secret: bundle.authData.oauth_token_secret,\n });\n }\n return req;\n};\n\nmodule.exports = {\n config,\n includeAccessToken,\n};\n\n```\n\n## `index.js`\n\n```js\nconst LikeTrigger = require('./triggers/like');\nconst authentication = require('./authentication');\n\n// We can roll up all our behaviors in an App.\nconst App = {\n // This is just shorthand to reference the installed dependencies you have. Zapier will\n // need to know these before we can upload\n version: require('./package.json').version,\n platformVersion: require('zapier-platform-core').version,\n\n authentication: authentication.config,\n\n // beforeRequest & afterResponse are optional hooks into the provided HTTP client\n beforeRequest: [authentication.includeAccessToken],\n\n afterResponse: [],\n\n // If you want to define optional resources to simplify creation of triggers, searches, creates - do that here!\n resources: {},\n\n // If you want your trigger to show up, you better include it here!\n triggers: {\n [LikeTrigger.key]: LikeTrigger,\n },\n\n // If you want your searches to show up, you better include it here!\n searches: {},\n\n // If you want your creates to show up, you better include it here!\n creates: {},\n};\n\n// Finally, export the app.\nmodule.exports = App;\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"zapier-platform-example-app-oauth1-tumblr\",\n \"version\": \"1.0.0\",\n \"description\": \"Tumblr OAuth V1 Example\",\n \"repository\": \"zapier/zapier-platform-example-app-oauth1-tumblr\",\n \"homepage\": \"https://zapier.com/\",\n \"author\": \"Chang-Hung Liang <chang-hung.liang@zapier.com>\",\n \"license\": \"BSD-3-Clause\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"mocha --recursive\"\n },\n \"engines\": {\n \"node\": \">=8.10.0\",\n \"npm\": \">=5.6.0\"\n },\n \"dependencies\": {\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"mocha\": \"^5.2.0\",\n \"should\": \"^13.2.0\"\n },\n \"private\": true\n}\n\n```\n\n## `test/index.js`\n\n```js\n/* globals describe, it */\n\nrequire('should');\n\n// Uncomment and use this to make test calls into your app:\n\n// const zapier = require('zapier-platform-core');\n// const App = require('../index');\n// const appTester = zapier.createAppTester(App);\n\ndescribe('My App', () => {\n it('should test something', (done) => {\n const x = 1;\n x.should.eql(1);\n\n // const bundle = { inputData: {} };\n // const results = appTester(App.triggers.SOME_TRIGGER.operation.perform, bundle);\n // results.length.should.eql(3);\n done();\n });\n});\n\n```\n\n## `triggers/like.js`\n\n```js\nconst perform = async (z, bundle) => {\n const url = 'https://api.tumblr.com/v2/user/likes';\n const response = await z.request(url);\n const result = response.data;\n return result.response.liked_posts || [];\n};\n\nmodule.exports = {\n key: 'like',\n noun: 'Like',\n\n display: {\n label: 'New Like',\n description: 'Triggers when you like a post.',\n },\n\n operation: {\n perform,\n sample: {\n blog_name: 'citriccomics',\n id: 3507845453,\n post_url: 'https://citriccomics.tumblr.com/post/3507845453',\n type: 'text',\n date: '2011-02-25 20:27:00 GMT',\n timestamp: 1298665620,\n state: 'published',\n format: 'html',\n reblog_key: 'b0baQtsl',\n tags: ['tumblrize', 'milky dog', 'mini comic'],\n note_count: 14,\n title: 'Milky Dog',\n body: '<p>Example body.</p>',\n },\n },\n};\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/oauth1-tumblr", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/oauth1-tumblr", "section": "templates", "tags": ["example", "oauth1", "template"], "related": ["zapier-platform init --template oauth1-tumblr"], "meta": {"files": ["index.js", "README.md", "package.json", "authentication.js", "test/index.js", "triggers/like.js"], "auth": "oauth1", "pattern": "example", "local": "repos/zapier-platform/example-apps/oauth1-tumblr"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:oauth1-twitter", "kind": "template", "key": "oauth1-twitter", "title": "Source template: oauth1-twitter", "summary": "Full example-app source (oauth1 / example).", "body": "# example-app `oauth1-twitter`\n\nAuth: `oauth1` · Pattern: `example`\n\n## `README.md`\n\n```md\n# \"OAuth1\" Twitter Example App For Zapier Platform\n\nRequires CLI **7.5.0** and above! A barebones app that has OAuth1 setup, using Twitter for example.\n\n> We recommend using the zapier-platform-cli and `zapier-platform init .`  to create an app - youll be presented with a list of currently available templates to start with.\n\n```\n\n## `authentication.js`\n\n```js\nconst _ = require('lodash');\n\nconst REQUEST_TOKEN_URL = 'https://api.twitter.com/oauth/request_token';\nconst AUTHORIZE_URL = 'https://api.twitter.com/oauth/authorize';\nconst ACCESS_TOKEN_URL = 'https://api.twitter.com/oauth/access_token';\n\nconst getRequestToken = async (z, bundle) => {\n const response = await z.request({\n url: REQUEST_TOKEN_URL,\n method: 'POST',\n auth: {\n oauth_consumer_key: process.env.CLIENT_ID,\n oauth_consumer_secret: process.env.CLIENT_SECRET,\n oauth_signature_method: 'HMAC-SHA1',\n oauth_callback: bundle.inputData.redirect_uri,\n oauth_version: '1.0', // Twitter says this should be 1.0\n },\n });\n return response.data;\n};\n\nconst getAccessToken = async (z, bundle) => {\n const response = await z.request({\n url: ACCESS_TOKEN_URL,\n method: 'POST',\n auth: {\n oauth_consumer_key: process.env.CLIENT_ID,\n oauth_consumer_secret: process.env.CLIENT_SECRET,\n oauth_token: bundle.inputData.oauth_token,\n oauth_token_secret: bundle.inputData.oauth_token_secret,\n oauth_verifier: bundle.inputData.oauth_verifier,\n },\n });\n return response.data;\n};\n\nconst config = {\n type: 'oauth1',\n oauth1Config: {\n // We have to define getRequestToken and getAccessToken functions to explicitly\n // parse the response like it has a form body here, since Twitter responds\n // 'text/html' for the Content-Type header\n getRequestToken,\n getAccessToken,\n\n authorizeUrl: {\n url: AUTHORIZE_URL,\n params: {\n oauth_token: '{{bundle.inputData.oauth_token}}',\n },\n },\n },\n test: {\n url: 'https://api.twitter.com/1.1/account/settings.json',\n },\n connectionLabel: '{{screen_name}}',\n};\n\n// A middleware that is run before z.request() actually makes the request. Here we're\n// adding necessary OAuth1 parameters to `auth` property of the request object.\nconst includeAccessToken = (req, z, bundle) => {\n if (\n bundle.authData &&\n bundle.authData.oauth_token &&\n bundle.authData.oauth_token_secret\n ) {\n // Just put your OAuth1 credentials in req.auth, Zapier will sign the request for\n // you.\n req.auth = req.auth || {};\n _.defaults(req.auth, {\n oauth_consumer_key: process.env.CLIENT_ID,\n oauth_consumer_secret: process.env.CLIENT_SECRET,\n oauth_token: bundle.authData.oauth_token,\n oauth_token_secret: bundle.authData.oauth_token_secret,\n });\n }\n return req;\n};\n\nmodule.exports = {\n config,\n includeAccessToken,\n};\n\n```\n\n## `index.js`\n\n```js\nconst LikeTrigger = require('./triggers/like');\nconst authentication = require('./authentication');\n\n// We can roll up all our behaviors in an App.\nconst App = {\n // This is just shorthand to reference the installed dependencies you have. Zapier will\n // need to know these before we can upload\n version: require('./package.json').version,\n platformVersion: require('zapier-platform-core').version,\n\n authentication: authentication.config,\n\n // beforeRequest & afterResponse are optional hooks into the provided HTTP client\n beforeRequest: [authentication.includeAccessToken],\n\n afterResponse: [],\n\n // If you want to define optional resources to simplify creation of triggers, searches, creates - do that here!\n resources: {},\n\n // If you want your trigger to show up, you better include it here!\n triggers: {\n [LikeTrigger.key]: LikeTrigger,\n },\n\n // If you want your searches to show up, you better include it here!\n searches: {},\n\n // If you want your creates to show up, you better include it here!\n creates: {},\n};\n\n// Finally, export the app.\nmodule.exports = App;\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"zapier-platform-example-app-oauth1-twitter\",\n \"version\": \"1.0.0\",\n \"description\": \"An OAuth1 example using Twitter.\",\n \"repository\": \"zapier/zapier-platform-example-app-oauth1-twitter\",\n \"homepage\": \"https://zapier.com/\",\n \"author\": \"Zapier <partners@zapier.com>\",\n \"license\": \"BSD-3-Clause\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"mocha --recursive\"\n },\n \"engines\": {\n \"node\": \">=8.10.0\",\n \"npm\": \">=5.6.0\"\n },\n \"dependencies\": {\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"mocha\": \"^5.2.0\",\n \"should\": \"^13.2.0\"\n },\n \"private\": true\n}\n\n```\n\n## `triggers/like.js`\n\n```js\nmodule.exports = {\n key: 'like',\n noun: 'Like',\n\n display: {\n label: 'New Like',\n description: 'Triggers when you like a tweet.',\n },\n\n operation: {\n perform: {\n url: 'https://api.twitter.com/1.1/favorites/list.json',\n },\n sample: {\n coordinates: null,\n truncated: false,\n favorited: true,\n created_at: 'Tue Sep 04 15:55:52 +0000 2012',\n id_str: '243014525132091393',\n in_reply_to_user_id_str: null,\n entities: {\n urls: [],\n hashtags: [],\n user_mentions: [],\n },\n text: \"Note to self: don't die during off-peak hours on a holiday weekend.\",\n contributors: null,\n id: 243014525132091400,\n retweet_count: 0,\n in_reply_to_status_id_str: null,\n geo: null,\n retweeted: false,\n in_reply_to_user_id: null,\n in_reply_to_screen_name: null,\n source: 'web',\n user: {\n profile_sidebar_fill_color: '252429',\n profile_background_tile: true,\n profile_sidebar_border_color: '181A1E',\n name: 'Sean Cook',\n profile_image_url:\n 'https://a0.twimg.com/profile_images/1751506047/dead_sexy_normal.JPG',\n location: 'San Francisco',\n created_at: 'Sat May 09 17:58:22 +0000 2009',\n follow_request_sent: false,\n is_translator: false,\n id_str: '38895958',\n profile_link_color: '2FC2EF',\n entities: {\n description: {\n urls: [],\n },\n },\n favourites_count: 594,\n url: null,\n default_profile: false,\n contributors_enabled: true,\n profile_image_url_https:\n 'https://si0.twimg.com/profile_images/1751506047/dead_sexy_normal.JPG',\n utc_offset: -28800,\n id: 38895958,\n listed_count: 191,\n profile_use_background_image: true,\n followers_count: 10659,\n protected: false,\n profile_text_color: '666666',\n lang: 'en',\n profile_background_color: '1A1B1F',\n time_zone: 'Pacific Time (US & Canada)',\n verified: false,\n profile_background_image_url_https:\n 'https://si0.twimg.com/profile_background_images/495742332/purty_wood.png',\n description:\n 'I taught your phone that thing you like. The Mobile Partner Engineer @Twitter. ',\n geo_enabled: true,\n notifications: false,\n default_profile_image: false,\n friends_count: 1186,\n profile_background_image_url:\n 'https://a0.twimg.com/profile_background_images/495742332/purty_wood.png',\n statuses_count: 2629,\n following: true,\n screen_name: 'theSeanCook',\n show_all_inline_media: true,\n },\n place: {\n name: 'San Francisco',\n country_code: 'US',\n country: 'United States',\n attributes: {},\n url: 'https://api.twitter.com/1/geo/id/5a110d312052166f.json',\n id: '5a110d312052166f',\n bounding_box: {\n coordinates: [\n [\n [-122.51368188, 37.70813196],\n [-122.35845384, 37.70813196],\n [-122.35845384, 37.83245301],\n [-122.51368188, 37.83245301],\n ],\n ],\n type: 'Polygon',\n },\n full_name: 'San Francisco, CA',\n place_type: 'city',\n },\n in_reply_to_status_id: null,\n },\n },\n};\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/oauth1-twitter", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/oauth1-twitter", "section": "templates", "tags": ["example", "oauth1", "template"], "related": ["zapier-platform init --template oauth1-twitter"], "meta": {"files": ["index.js", "README.md", "package.json", "authentication.js", "triggers/like.js"], "auth": "oauth1", "pattern": "example", "local": "repos/zapier-platform/example-apps/oauth1-twitter"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:oauth2", "kind": "template", "key": "oauth2", "title": "Source template: oauth2", "summary": "Full example-app source (oauth2 / example).", "body": "# example-app `oauth2`\n\nAuth: `oauth2` · Pattern: `example`\n\n## `README.md`\n\n```md\n# oauth2\n\nThis Zapier integration project is generated by the `zapier-platform init` CLI command.\n\nThese are what you normally do next:\n\n```bash\n# Install dependencies\nnpm install # or you can use yarn\n\n# Run tests\nzapier-platform test\n\n# Register the integration on Zapier if you haven't\nzapier-platform register \"App Title\"\n\n# Or you can link to an existing integration on Zapier\nzapier-platform link\n\n# Push it to Zapier\nzapier-platform push\n```\n\nThen, to add more features, you can use the `zapier-platform scaffold` command, for example:\n\n```bash\n# Add a trigger\nzapier-platform scaffold trigger contact\n\n# Add an action\nzapier-platform scaffold create contact\n``` \n\nFind out more on the latest docs: https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md.\n\n```\n\n## `authentication.js`\n\n```js\n'use strict';\n\nconst getAccessToken = async (z, bundle) => {\n const response = await z.request({\n url: 'https://auth-json-server.zapier-staging.com/oauth/access-token',\n method: 'POST',\n body: {\n client_id: process.env.CLIENT_ID,\n client_secret: process.env.CLIENT_SECRET,\n grant_type: 'authorization_code',\n code: bundle.inputData.code,\n\n // Extra data can be pulled from the querystring. For instance:\n // 'accountDomain': bundle.cleanedRequest.querystring.accountDomain\n },\n headers: { 'content-type': 'application/x-www-form-urlencoded' },\n });\n\n // If you're using core v9.x or older, you should call response.throwForStatus()\n // or verify response.status === 200 before you continue.\n\n // This function should return `access_token`.\n // If your app does an app refresh, then `refresh_token` should be returned here\n // as well\n return {\n access_token: response.data.access_token,\n refresh_token: response.data.refresh_token,\n };\n};\n\nconst refreshAccessToken = async (z, bundle) => {\n const response = await z.request({\n url: 'https://auth-json-server.zapier-staging.com/oauth/refresh-token',\n method: 'POST',\n body: {\n client_id: process.env.CLIENT_ID,\n client_secret: process.env.CLIENT_SECRET,\n grant_type: 'refresh_token',\n refresh_token: bundle.authData.refresh_token,\n },\n headers: { 'content-type': 'application/x-www-form-urlencoded' },\n });\n\n // If you're using core v9.x or older, you should call response.throwForStatus()\n // or verify response.status === 200 before you continue.\n\n // This function should return `access_token`.\n // If the refresh token stays constant, no need to return it.\n // If the refresh token does change, return it here to update the stored value in\n // Zapier\n return {\n access_token: response.data.access_token,\n refresh_token: response.data.refresh_token,\n };\n};\n\n// You want to make a request to an endpoint that is either specifically designed\n// to test auth, or one that every user will have access to. eg: `/me`.\n// By returning the entire request object, you have access to the request and\n// response data for testing purposes. Your connection label can access any data\n// from the returned response using the `json.` prefix. eg: `{{json.username}}`.\nconst test = (z, bundle) =>\n z.request({ url: 'https://auth-json-server.zapier-staging.com/me' });\n\nmodule.exports = {\n // OAuth2 is a web authentication standard. There are a lot of configuration\n // options that will fit most any situation.\n type: 'oauth2',\n oauth2Config: {\n authorizeUrl: {\n url: 'https://auth-json-server.zapier-staging.com/oauth/authorize',\n params: {\n client_id: '{{process.env.CLIENT_ID}}',\n state: '{{bundle.inputData.state}}',\n redirect_uri: '{{bundle.inputData.redirect_uri}}',\n response_type: 'code',\n },\n },\n getAccessToken,\n refreshAccessToken,\n autoRefresh: true,\n },\n\n // Define any input app's auth requires here. The user will be prompted to enter\n // this info when they connect their account.\n fields: [],\n\n // The test method allows Zapier to verify that the credentials a user provides\n // are valid. We'll execute this method whenever a user connects their account for\n // the first time.\n test,\n\n // This template string can access all the data returned from the auth test. If\n // you return the test object, you'll access the returned data with a label like\n // `{{json.X}}`. If you return `response.data` from your test, then your label can\n // be `{{X}}`. This can also be a function that returns a label. That function has\n // the standard args `(z, bundle)` and data returned from the test can be accessed\n // in `bundle.inputData.X`.\n connectionLabel: '{{json.username}}',\n};\n\n```\n\n## `index.js`\n\n```js\nconst authentication = require('./authentication');\nconst { befores = [], afters = [] } = require('./middleware');\n\nmodule.exports = {\n // This is just shorthand to reference the installed dependencies you have.\n // Zapier will need to know these before we can upload.\n version: require('./package.json').version,\n platformVersion: require('zapier-platform-core').version,\n\n authentication,\n\n beforeRequest: [...befores],\n\n afterResponse: [...afters],\n\n // If you want your trigger to show up, you better include it here!\n triggers: {},\n\n // If you want your searches to show up, you better include it here!\n searches: {},\n\n // If you want your creates to show up, you better include it here!\n creates: {},\n\n resources: {},\n};\n\n```\n\n## `middleware.js`\n\n```js\n'use strict';\n\n// This function runs before every outbound request. You can have as many as you\n// need. They'll need to each be registered in your index.js file.\nconst includeBearerToken = (request, z, bundle) => {\n if (bundle.authData.access_token) {\n request.headers.Authorization = `Bearer ${bundle.authData.access_token}`;\n }\n\n return request;\n};\n\nmodule.exports = { befores: [includeBearerToken], afters: [] };\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"oauth2\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"scripts\": {\n \"test\": \"jest --testTimeout 10000\"\n },\n \"dependencies\": {\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"jest\": \"^29.6.0\"\n },\n \"private\": true,\n \"main\": \"index.js\"\n}\n\n```\n\n## `test/authentication.test.js`\n\n```js\n/* globals describe, it, expect, beforeAll */\n\nconst zapier = require('zapier-platform-core');\n\nzapier.tools.env.inject(); // read from the .env file\n\nconst App = require('../index');\nconst appTester = zapier.createAppTester(App);\n\n// Only here so the tests out of the box.\n// You should create a `.env` file and populate it with the necessarily configuration\n// it should look like:\n/*\n CLIENT_ID=1234\n CLIENT_SECRET=asdf\n*/\n// then you can delete the following 2 lines\nprocess.env.CLIENT_ID = process.env.CLIENT_ID || '1234';\nprocess.env.CLIENT_SECRET = process.env.CLIENT_SECRET || 'asdf';\n\ndescribe('oauth2 app', () => {\n beforeAll(() => {\n // It's a good idea to store your Client ID and Secret in the environment rather than in code.\n if (!(process.env.CLIENT_ID && process.env.CLIENT_SECRET)) {\n throw new Error(\n `Before running the tests, make sure CLIENT_ID and CLIENT_SECRET are available in the environment.`,\n );\n }\n });\n\n it('generates an authorize URL', async () => {\n const bundle = {\n // In production, these will be generated by Zapier and set automatically\n inputData: {\n state: '4444',\n redirect_uri: 'https://zapier.com/',\n },\n environment: {\n CLIENT_ID: process.env.CLIENT_ID,\n CLIENT_SECRET: process.env.CLIENT_SECRET,\n },\n };\n\n const authorizeUrl = await appTester(\n App.authentication.oauth2Config.authorizeUrl,\n bundle,\n );\n\n expect(authorizeUrl).toBe(\n 'https://auth-json-server.zapier-staging.com/oauth/authorize?client_id=1234&state=4444&redirect_uri=https%3A%2F%2Fzapier.com%2F&response_type=code',\n );\n });\n\n it('can fetch an access token', async () => {\n const bundle = {\n inputData: {\n // In production, Zapier passes along whatever code your API set in the query params when it redirects\n // the user's browser to the `redirect_uri`\n code: 'one_time_code',\n },\n environment: {\n CLIENT_ID: process.env.CLIENT_ID,\n CLIENT_SECRET: process.env.CLIENT_SECRET,\n },\n cleanedRequest: {\n querystring: {\n accountDomain: 'test-account',\n code: 'one_time_code',\n },\n },\n rawRequest: {\n querystring: '?accountDomain=test-account&code=one_time_code',\n },\n };\n\n const result = await appTester(\n App.authentication.oauth2Config.getAccessToken,\n bundle,\n );\n\n expect(result.access_token).toBe('a_token');\n expect(result.refresh_token).toBe('a_refresh_token');\n });\n\n it('can refresh the access token', async () => {\n const bundle = {\n // In production, Zapier provides these. For testing, we have hard-coded them.\n // When writing tests for your own app, you should consider exporting them and doing process.env.MY_ACCESS_TOKEN\n authData: {\n access_token: 'a_token',\n refresh_token: 'a_refresh_token',\n },\n environment: {\n CLIENT_ID: process.env.CLIENT_ID,\n CLIENT_SECRET: process.env.CLIENT_SECRET,\n },\n };\n\n const result = await appTester(\n App.authentication.oauth2Config.refreshAccessToken,\n bundle,\n );\n expect(result.access_token).toBe('a_token');\n });\n\n it('includes the access token in future requests', async () => {\n const bundle = {\n authData: {\n access_token: 'a_token',\n refresh_token: 'a_refresh_token',\n },\n };\n\n const response = await appTester(App.authentication.test, bundle);\n expect(response.data).toHaveProperty('username');\n expect(response.data.username).toBe('Bret');\n });\n});\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/oauth2", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/oauth2", "section": "templates", "tags": ["example", "oauth2", "template"], "related": ["zapier-platform init --template oauth2"], "meta": {"files": ["index.js", "README.md", "package.json", "middleware.js", "authentication.js", "test/authentication.test.js"], "auth": "oauth2", "pattern": "example", "local": "repos/zapier-platform/example-apps/oauth2"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:oauth2-typescript", "kind": "template", "key": "oauth2-typescript", "title": "Source template: oauth2-typescript", "summary": "Full example-app source (oauth2 / example).", "body": "# example-app `oauth2-typescript`\n\nAuth: `oauth2` · Pattern: `example`\n\n## `README.md`\n\n```md\n# oauth2-typescript\n\nThis Zapier integration project is generated by the `zapier-platform init` CLI command.\n\nThese are what you normally do next:\n\n```bash\n# Install dependencies\nnpm install # or you can use yarn\n\n# Run tests\nzapier-platform test\n\n# Register the integration on Zapier if you haven't\nzapier-platform register \"App Title\"\n\n# Or you can link to an existing integration on Zapier\nzapier-platform link\n\n# Push it to Zapier\nzapier-platform push\n```\n\nThen, to add more features, you can use the `zapier-platform scaffold` command, for example:\n\n```bash\n# Add a trigger\nzapier-platform scaffold trigger contact\n\n# Add an action\nzapier-platform scaffold create contact\n``` \n\nFind out more on the latest docs: https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md.\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"oauth2-typescript\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"scripts\": {\n \"test\": \"npm run build && vitest --run\",\n \"clean\": \"rimraf ./dist ./build\",\n \"build\": \"npm run clean && tsc\",\n \"_zapier-build\": \"npm run build\"\n },\n \"dependencies\": {\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"rimraf\": \"^5.0.10\",\n \"typescript\": \"5.6.2\",\n \"vitest\": \"^2.1.2\"\n },\n \"private\": true,\n \"exports\": \"./dist/index.js\",\n \"type\": \"module\"\n}\n\n```\n\n## `src/authentication.ts`\n\n```ts\nimport type { ZObject, Bundle, Authentication } from 'zapier-platform-core';\n\nconst getAccessToken = async (z: ZObject, bundle: Bundle) => {\n const response = await z.request({\n url: 'https://auth-json-server.zapier-staging.com/oauth/access-token',\n method: 'POST',\n body: {\n client_id: process.env.CLIENT_ID,\n client_secret: process.env.CLIENT_SECRET,\n grant_type: 'authorization_code',\n code: bundle.inputData.code,\n\n // Extra data can be pulled from the querystring. For instance:\n // 'accountDomain': bundle.cleanedRequest.querystring.accountDomain\n },\n headers: { 'content-type': 'application/x-www-form-urlencoded' },\n });\n\n // If you're using core v9.x or older, you should call response.throwForStatus()\n // or verify response.status === 200 before you continue.\n\n // This function should return `access_token`.\n // If your app does an app refresh, then `refresh_token` should be returned here\n // as well\n return {\n access_token: response.data.access_token,\n refresh_token: response.data.refresh_token,\n };\n};\n\nconst refreshAccessToken = async (z: ZObject, bundle: Bundle) => {\n const response = await z.request({\n url: 'https://auth-json-server.zapier-staging.com/oauth/refresh-token',\n method: 'POST',\n body: {\n client_id: process.env.CLIENT_ID,\n client_secret: process.env.CLIENT_SECRET,\n grant_type: 'refresh_token',\n refresh_token: bundle.authData.refresh_token,\n },\n headers: { 'content-type': 'application/x-www-form-urlencoded' },\n });\n\n // If you're using core v9.x or older, you should call response.throwForStatus()\n // or verify response.status === 200 before you continue.\n\n // This function should return `access_token`.\n // If the refresh token stays constant, no need to return it.\n // If the refresh token does change, return it here to update the stored value in\n // Zapier\n return {\n access_token: response.data.access_token,\n refresh_token: response.data.refresh_token,\n };\n};\n\n// You want to make a request to an endpoint that is either specifically designed\n// to test auth, or one that every user will have access to. eg: `/me`.\n// By returning the entire request object, you have access to the request and\n// response data for testing purposes. Your connection label can access any data\n// from the returned response using the `json.` prefix. eg: `{{json.username}}`.\nconst test = (z: ZObject, bundle: Bundle) =>\n z.request({ url: 'https://auth-json-server.zapier-staging.com/me' });\n\nexport default {\n // OAuth2 is a web authentication standard. There are a lot of configuration\n // options that will fit most any situation.\n type: 'oauth2',\n oauth2Config: {\n authorizeUrl: {\n url: 'https://auth-json-server.zapier-staging.com/oauth/authorize',\n params: {\n client_id: '{{process.env.CLIENT_ID}}',\n state: '{{bundle.inputData.state}}',\n redirect_uri: '{{bundle.inputData.redirect_uri}}',\n response_type: 'code',\n },\n },\n getAccessToken,\n refreshAccessToken,\n autoRefresh: true,\n },\n\n // Define any input app's auth requires here. The user will be prompted to enter\n // this info when they connect their account.\n fields: [],\n\n // The test method allows Zapier to verify that the credentials a user provides\n // are valid. We'll execute this method whenever a user connects their account for\n // the first time.\n test,\n\n // This template string can access all the data returned from the auth test. If\n // you return the test object, you'll access the returned data with a label like\n // `{{json.X}}`. If you return `response.data` from your test, then your label can\n // be `{{X}}`. This can also be a function that returns a label. That function has\n // the standard args `(z: ZObject, bundle: Bundle)` and data returned from the\n // test can be accessed in `bundle.inputData.X`.\n connectionLabel: '{{json.username}}',\n} satisfies Authentication;\n\n```\n\n## `src/index.ts`\n\n```ts\nimport zapier, { defineApp } from 'zapier-platform-core';\n\nimport packageJson from '../package.json' with { type: 'json' };\n\nimport authentication from './authentication.js';\nimport { befores, afters } from './middleware.js';\n\nexport default defineApp({\n version: packageJson.version,\n platformVersion: zapier.version,\n\n authentication,\n beforeRequest: [...befores],\n afterResponse: [...afters],\n\n // Add your triggers here for them to show up!\n triggers: {},\n\n // Add your creates here for them to show up!\n creates: {},\n});\n\n```\n\n## `src/middleware.ts`\n\n```ts\nimport type { ZObject, Bundle, Authentication } from 'zapier-platform-core';\n\n// This function runs before every outbound request. You can have as many as you\n// need. They'll need to each be registered in your index.js file.\nconst includeBearerToken = (request, z: ZObject, bundle: Bundle) => {\n if (bundle.authData.access_token) {\n request.headers.Authorization = `Bearer ${bundle.authData.access_token}`;\n }\n\n return request;\n};\n\nexport const befores = [includeBearerToken];\n\nexport const afters = [];\n\n```\n\n## `src/test/authentication.test.ts`\n\n```ts\nimport { describe, expect, it, beforeAll } from 'vitest';\nimport zapier from 'zapier-platform-core';\n\nimport App from '../index.js';\nconst appTester = zapier.createAppTester(App);\n\n// Only defining the env vars here so the tests out of the box.\n// You should create a `.env` file and populate it with the necessarily configuration\n// it should look like:\n/*\n CLIENT_ID=1234\n CLIENT_SECRET=asdf\n*/\n// then you can delete the following 2 lines\nprocess.env.CLIENT_ID = process.env.CLIENT_ID || '1234';\nprocess.env.CLIENT_SECRET = process.env.CLIENT_SECRET || 'asdf';\n\ndescribe('authentication', () => {\n beforeAll(() => {\n // It's a good idea to store your Client ID and Secret in the environment rather than in code.\n if (!(process.env.CLIENT_ID && process.env.CLIENT_SECRET)) {\n throw new Error(\n `Before running the tests, make sure CLIENT_ID and CLIENT_SECRET are available in the environment.`,\n );\n }\n });\n\n it('generates an authorize URL', async () => {\n const bundle = {\n // In production, these will be generated by Zapier and set automatically\n inputData: {\n state: '4444',\n redirect_uri: 'https://zapier.com/',\n },\n environment: {\n CLIENT_ID: process.env.CLIENT_ID,\n CLIENT_SECRET: process.env.CLIENT_SECRET,\n },\n };\n\n const authorizeUrl = await appTester(\n App.authentication.oauth2Config.authorizeUrl,\n bundle,\n );\n\n expect(authorizeUrl).toBe(\n 'https://auth-json-server.zapier-staging.com/oauth/authorize?client_id=1234&state=4444&redirect_uri=https%3A%2F%2Fzapier.com%2F&response_type=code',\n );\n });\n\n it('can fetch an access token', async () => {\n const bundle = {\n inputData: {\n // In production, Zapier passes along whatever code your API set in the query params when it redirects\n // the user's browser to the `redirect_uri`\n code: 'one_time_code',\n },\n environment: {\n CLIENT_ID: process.env.CLIENT_ID,\n CLIENT_SECRET: process.env.CLIENT_SECRET,\n },\n cleanedRequest: {\n querystring: {\n accountDomain: 'test-account',\n code: 'one_time_code',\n },\n },\n rawRequest: {\n querystring: '?accountDomain=test-account&code=one_time_code',\n },\n };\n\n const result = await appTester(\n App.authentication.oauth2Config.getAccessToken,\n bundle,\n );\n\n expect(result.access_token).toBe('a_token');\n expect(result.refresh_token).toBe('a_refresh_token');\n });\n\n it('can refresh the access token', async () => {\n const bundle = {\n // In production, Zapier provides these. For testing, we have hard-coded them.\n // When writing tests for your own app, you should consider exporting them and doing process.env.MY_ACCESS_TOKEN\n authData: {\n access_token: 'a_token',\n refresh_token: 'a_refresh_token',\n },\n environment: {\n CLIENT_ID: process.env.CLIENT_ID,\n CLIENT_SECRET: process.env.CLIENT_SECRET,\n },\n };\n\n const result = await appTester(\n App.authentication.oauth2Config.refreshAccessToken,\n bundle,\n );\n expect(result.access_token).toBe('a_token');\n });\n\n it('includes the access token in future requests', async () => {\n const bundle = {\n authData: {\n access_token: 'a_token',\n refresh_token: 'a_refresh_token',\n },\n };\n\n const response = await appTester(App.authentication.test, bundle);\n expect(response.data).toHaveProperty('username');\n expect(response.data.username).toBe('Bret');\n });\n});\n\n```\n\n## `tsconfig.json`\n\n```json\n{\n \"compilerOptions\": {\n \"target\": \"ESNext\",\n \"module\": \"NodeNext\",\n \"moduleResolution\": \"NodeNext\",\n \"resolveJsonModule\": true,\n \"esModuleInterop\": true,\n \"noUncheckedIndexedAccess\": true,\n \"isolatedModules\": true,\n \"noImplicitAny\": false,\n \"skipLibCheck\": true,\n \"outDir\": \"./dist\",\n \"rootDir\": \"./src\",\n \"strict\": true\n },\n \"include\": [\"./src/**/*.ts\"],\n \"exclude\": [\"./**/*.test.ts\"]\n}\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/oauth2-typescript", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/oauth2-typescript", "section": "templates", "tags": ["example", "oauth2", "template"], "related": ["zapier-platform init --template oauth2-typescript"], "meta": {"files": ["README.md", "package.json", "tsconfig.json", "src/middleware.ts", "src/authentication.ts", "src/index.ts", "src/test/authentication.test.ts"], "auth": "oauth2", "pattern": "example", "local": "repos/zapier-platform/example-apps/oauth2-typescript"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:onedrive", "kind": "template", "key": "onedrive", "title": "Source template: onedrive", "summary": "Full example-app source (n/a / example).", "body": "# example-app `onedrive`\n\nAuth: `n/a` · Pattern: `example`\n\n## `.eslintrc.json`\n\n```json\n{\n \"extends\": \"eslint:recommended\",\n \"env\": {\n \"es6\": true,\n \"node\": true\n },\n \"rules\": {\n \"arrow-parens\": [2, \"always\"],\n \"camelcase\": 0,\n \"comma-dangle\": 0,\n \"comma-spacing\": 2,\n \"consistent-return\": 2,\n \"curly\": [2, \"all\"],\n \"dot-notation\": [2, { \"allowKeywords\": true }],\n \"eol-last\": 2,\n \"eqeqeq\": [2, \"smart\"],\n \"indent\": [2, 2],\n \"jsx-quotes\": [2, \"prefer-double\"],\n \"key-spacing\": [2, { \"beforeColon\": false, \"afterColon\": true }],\n \"keyword-spacing\": 2,\n \"new-cap\": 0,\n \"new-parens\": 2,\n \"no-alert\": 2,\n \"no-array-constructor\": 2,\n \"no-caller\": 2,\n \"no-console\": [2, { \"allow\": [\"info\", \"warn\", \"error\"] }],\n \"no-delete-var\": 2,\n \"no-eval\": 2,\n \"no-extend-native\": 2,\n \"no-extra-bind\": 2,\n \"no-fallthrough\": 2,\n \"no-implied-eval\": 2,\n \"no-iterator\": 2,\n \"no-label-var\": 2,\n \"no-labels\": 2,\n \"no-lone-blocks\": 2,\n \"no-loop-func\": 2,\n \"no-mixed-spaces-and-tabs\": [2, false],\n \"no-multi-spaces\": 2,\n \"no-multi-str\": 2,\n \"no-native-reassign\": 2,\n \"no-new\": 2,\n \"no-new-func\": 2,\n \"no-new-object\": 2,\n \"no-new-wrappers\": 2,\n \"no-octal\": 2,\n \"no-octal-escape\": 2,\n \"no-process-exit\": 2,\n \"no-proto\": 2,\n \"no-redeclare\": 2,\n \"no-return-assign\": 2,\n \"no-script-url\": 2,\n \"no-sequences\": 2,\n \"no-shadow\": 2,\n \"no-shadow-restricted-names\": 2,\n \"no-spaced-func\": 2,\n \"no-trailing-spaces\": 2,\n \"no-undef\": 2,\n \"no-undef-init\": 2,\n \"no-underscore-dangle\": 0,\n \"no-unused-expressions\": 2,\n \"no-unused-vars\": [\n 2,\n { \"vars\": \"all\", \"args\": \"after-used\", \"varsIgnorePattern\": \"should\" }\n ],\n \"no-use-before-define\": 2,\n \"no-with\": 2,\n \"quotes\": [\n 2,\n \"single\",\n { \"avoidEscape\": true, \"allowTemplateLiterals\": true }\n ],\n \"semi\": 2,\n \"semi-spacing\": [2, { \"before\": false, \"after\": true }],\n \"space-infix-ops\": 2,\n \"space-unary-ops\": [2, { \"words\": true, \"nonwords\": false }],\n \"strict\": [0, \"never\"],\n \"yoda\": [2, \"never\"]\n },\n \"globals\": {\n \"describe\": true,\n \"before\": true,\n \"after\": true,\n \"beforeEach\": true,\n \"afterEach\": true,\n \"it\": true\n },\n \"parserOptions\": {\n \"ecmaVersion\": 7,\n \"sourceType\": \"module\"\n }\n}\n\n```\n\n## `README.md`\n\n```md\n# Example App - OneDrive\n\nThis is an example CLI App for the Zapier Developer Platform. It uses the OneDrive API as the target, showing what a\nfull-featured app looks like. It follows the best practices for building an app on Zapier.\n\nWhat it demonstrates:\n\n * OAuth2\n * File Handling\n * Hydration\n * `beforeRequest` handler (and how to skip it for a specific call)\n * Resources\n * Breaking an app up into maintable pieces\n\nThroughout the code we've added `CODE TIP` and `UX TIP` comments. These are good spots to find out some of the best\npractices and gotchas you may run into.\n\n## Getting Started\n\nFor a quicker primer on the OneDrive API see [here](https://dev.onedrive.com/getting-started.htm).\n\nAlso note, this app is not one you can download and start using immediately. Since it relies on the OneDrive API,\nthere is some out-of-band setup that you must complete if you want to be able to use the app on zapier.com. We walk you\nthrough it all, but be prepared!\n\n### 1. Install\n\nTo pull down the code and install the needed dependencies, run:\n\n```bash\nzapier-platform init --template=onedrive ./\nnpm install\n```\n> We recommend using the zapier-platform-cli and `zapier-platform init .`  to create an app - youll be presented with a list of currently available templates to start with.\n\n### 2. Seeing Your App on zapier.com\n\nThe first step is to do `zapier-platform register 'My Example OneDrive App'`. This logs you in and tells Zapier about your new app.\n\nNow try a `zapier-platform push`. At this point, you can go to zapier.com/app/editor and see your app in the Editor.\nYou won't be able to use the app yet (there are a couple steps required before auth works), but this gives you\na feel for some of the basic commands of the CLI tool.\n\n### 3. Register a Microsoft App\n\nThe OneDrive API follows a typical OAuth2 flow that requires your app to have a `CLIENT_ID` and `CLIENT_SECRET`. For\nsecurity reasons, we cannot include those for you, so you need to head over to `https://apps.dev.microsoft.com/`\nand register to obtain your own. When registering your app in MS, the minimal information you need to setup is:\n\n1. App Name - Can be anything, like 'My Example Zapier App'\n1. Application Secret - Generate a new password, copying that password somewhere for later\n1. Platform - Choose web. For Redirect URL, run `zapier-platform describe --format=json | grep 'Redirect URI'` in your terminal and paste in the URI provided by Zapier\n1. Click Save\n\nYou now need to tell Zapier what `CLIENT_ID` and `CLIENT_SECRET` to use when doing the OAuth2 flow. OneDrive uses\nthe Applicaiton ID of the app you just registered as the `CLIENT_ID`, and the Application Secret as the `CLIENT_SECRET`.\nYou can set those in Zapier like so:\n\n```bash\nzapier-platform env 1.0.0 CLIENT_ID <app_id>\nzapier-platform env 1.0.0 CLIENT_SECRET <app_secret>\n```\n\nYou should now be able to go back to zapier.com and connect your OneDrive account!\n\n### 4. Exploring\n\nAt this point you have a fully working Zapier app you can build Zaps with. Feel free to make tweaks to your app\nlocally, do a `zapier-platform push`, and see the changes take effect in production right away.\n\n## Testing\n\nThe tests are provided as an example of how to write good tests, along with stubs to give an idea of what scenarios to\ncover. If you want to actually run the test suite, you need to do a couple things.\n\nFirst is to manually walk through the OAuth2 flow and capture an access token and refresh token. You can then do:\n\n```bash\nexport ACCESS_TOKEN='<access_token>'\nexport REFRESH_TOKEN='<refresh_token>'\n```\n\nThe tests will pick those up and run with those credentials.\n\nThe second thing you need to do is update `TEST_RESOURCES` in `test/test-utils.js` with IDs and folder names in your\nOneDrive account. Once that is updated, you should be able to do:\n\n`zapier-platform test`\n\n```\n\n## `authentication.js`\n\n```js\n'use strict';\n\nconst baseOauthUrl = 'https://login.microsoftonline.com/common/oauth2';\n// To get your OAuth2 redirect URI, run `zapier describe` and update this variable.\n// Will looke like 'https://zapier.com/dashboard/auth/oauth/return/App123CLIAPI/'\nconst redirectUri = '';\n\nconst getAuthorizeURL = (z, bundle) => {\n let url = `${baseOauthUrl}/v2.0/authorize`;\n\n const urlParts = [\n `client_id=${process.env.CLIENT_ID}`,\n `redirect_uri=${encodeURIComponent(bundle.inputData.redirect_uri)}`,\n 'response_type=code',\n ];\n\n if (bundle.inputData.accountType === 'business') {\n url = `${baseOauthUrl}/authorize`;\n } else {\n urlParts.push(`state=${bundle.inputData.state}`);\n }\n\n const finalUrl = `${url}?${urlParts.join('&')}`;\n\n return finalUrl;\n};\n\nconst getAccessToken = (z, bundle) => {\n let url = `${baseOauthUrl}/v2.0/token`;\n\n const body = {\n code: bundle.inputData.code,\n client_id: process.env.CLIENT_ID,\n client_secret: process.env.CLIENT_SECRET,\n grant_type: 'authorization_code',\n };\n\n if (bundle.inputData.accountType === 'business') {\n url = `${baseOauthUrl}/token`;\n body.redirect_uri = redirectUri;\n body.resource = 'https://graph.microsoft.com/';\n }\n\n const promise = z.request(url, {\n method: 'POST',\n body,\n headers: {\n 'content-type': 'application/x-www-form-urlencoded',\n },\n });\n\n return promise.then((response) => ({\n access_token: response.data.access_token,\n refresh_token: response.data.refresh_token,\n id_token: response.data.id_token,\n }));\n};\n\nconst refreshAccessToken = (z, bundle) => {\n let url = `${baseOauthUrl}/v2.0/token`;\n\n const body = {\n refresh_token: bundle.authData.refresh_token,\n client_id: process.env.CLIENT_ID,\n client_secret: process.env.CLIENT_SECRET,\n grant_type: 'refresh_token',\n };\n\n if (bundle.authData.accountType === 'business') {\n url = `${baseOauthUrl}/token`;\n body.redirect_uri = redirectUri;\n body.resource = 'https://graph.microsoft.com/';\n }\n\n const promise = z.request(url, {\n method: 'POST',\n body,\n headers: {\n 'content-type': 'application/x-www-form-urlencoded',\n },\n });\n\n return promise.then((response) => ({\n access_token: response.data.access_token,\n refresh_token: response.data.refresh_token,\n id_token: response.data.id_token,\n }));\n};\n\n// The test call Zapier makes to ensure an access token is valid\n// UX TIP: Hit an endpoint that always returns data with valid credentials,\n// like a /profile or /me endpoint. That way the success/failure is related to\n// the token and not because the user didn't happen to have a recently created record.\nconst testAuth = (z) => {\n const promise = z.request({\n url: 'https://graph.microsoft.com/v1.0/me',\n });\n\n return promise.then((response) => response.data);\n};\n\nmodule.exports = {\n type: 'oauth2',\n connectionLabel: '{{bundle.inputData.userPrincipalName}}',\n oauth2Config: {\n authorizeUrl: getAuthorizeURL,\n getAccessToken,\n refreshAccessToken,\n // Set so Zapier automatically checks for 401s and calls refreshAccessToken\n autoRefresh: true,\n // offline_access is necessary for the refresh_token\n scope: 'User.Read Files.ReadWrite.All offline_access',\n },\n test: testAuth,\n fields: [\n {\n key: 'accountType',\n label: 'Account Type',\n choices: {\n personal: 'Personal - live.com/outlook.com',\n business: 'Business - Work or School',\n },\n default: 'personal',\n required: true,\n },\n ],\n};\n\n```\n\n## `before-handlers.js`\n\n```js\n'use strict';\n\n// This adds the needed auth header to a request. By registering this on the\n// app's `beforeRequest` section, every z.request() call will run this function.\nconst includeBearerToken = (request, z, bundle) => {\n if (bundle.authData.access_token) {\n request.headers.Authorization = `Bearer ${bundle.authData.access_token}`;\n }\n return request;\n};\n\nmodule.exports = {\n includeBearerToken,\n};\n\n```\n\n## `constants.js`\n\n```js\n'use strict';\n\nconst BASE_ITEM_URL = 'https://graph.microsoft.com/v1.0';\n\nconst BIG_FILE_MSG = 'File contents too big.';\nconst BINARY_CONTENT_MSG = 'Binary contents unsupported.';\n\nmodule.exports = {\n BASE_ITEM_URL,\n BIG_FILE_MSG,\n BINARY_CONTENT_MSG,\n};\n\n```\n\n## `creates/text-file.js`\n\n```js\n'use strict';\n\nconst utils = require('../utils');\nconst getStringByteSize = utils.getStringByteSize;\nconst baseItem = require('../resources/base-item');\nconst fileResource = require('../resources/file');\n\nconst createTextFile = (z, bundle) => {\n const folder = bundle.inputData.folder || '';\n let name = `${bundle.inputData.name}.txt`;\n\n // Remove potential duplicate extension\n if (name.endsWith('.txt.txt')) {\n name = name.slice(0, -4);\n }\n\n const fileSize = getStringByteSize(bundle.inputData.file);\n const contentType = 'text/plain; charset=UTF-8';\n\n return baseItem.handleCreateWithSession(\n z,\n bundle,\n bundle.inputData.file,\n fileSize,\n contentType,\n folder,\n name,\n );\n};\n\nmodule.exports = {\n key: 'textFile',\n noun: 'Text File',\n\n display: {\n label: 'Create New Text File',\n description:\n 'Creates a brand new text file from plain text content you specify.',\n },\n\n operation: {\n inputFields: [\n {\n key: 'folder',\n type: 'string',\n label: 'Folder',\n required: false,\n dynamic: 'folderList._path.name',\n helpText:\n 'Folder where to place the file. Keep clicking the dropdown to go inside folders. Defaults to the top-level folder if left blank.',\n },\n {\n key: 'file',\n type: 'text',\n label: 'File',\n required: true,\n helpText: 'Plain text content to put inside the new text file.',\n },\n {\n key: 'name',\n type: 'string',\n label: 'Name of New File',\n required: true,\n helpText:\n 'Specify the name of this file. \".txt\" will always be appended.',\n },\n ],\n\n perform: createTextFile,\n\n // CODE TIP: If you define a resource and additional operations on that\n // resource, you can simply import the resource and re-use parts of the\n // definition in the other operations, like here. In this case, creating a\n // text file and uploading a file are the same endpoint in the OneDrive API\n // so the sample and output are the same for each.\n sample: fileResource.sample,\n\n outputFields: fileResource.outputFields,\n },\n};\n\n```\n\n## `hydrators.js`\n\n```js\n'use strict';\n\nconst utils = require('./utils');\nconst handleError = utils.handleError;\nconst getStringByteSize = utils.getStringByteSize;\nconst {\n BASE_ITEM_URL,\n BIG_FILE_MSG,\n BINARY_CONTENT_MSG,\n} = require('./constants');\n\nconst getFileContents = (z, bundle) => {\n const options = {\n url: `${BASE_ITEM_URL}/me/drive/items/${bundle.inputData.id}/content`,\n };\n\n return z\n .request(options)\n .then((response) => {\n const fileContents = response.content;\n const fileSize = getStringByteSize(fileContents);\n\n // UX TIP: It's good to be mindful of how users will consume the outputs\n // of your app and how those outputs travel through Zapier.\n // In this scenario, users asked for the full content of a file so they\n // could map it into the body of an email vs. adding it as an attachment.\n // Cool workflow, but there are limits to passing around large payloads.\n // Here we compromise and hydrate the full content of the file for the\n // user, but only allow it through if it's under a sane size limit. That\n // way we don't send MBs of text through Zapier in every task. Note that\n // this does not prevent the user from transfering large files in Zaps, as\n // file fields are handled differently. This is specifically around our\n // app providing a field that the user wants to map into text inputs in\n // other Actions.\n if (fileSize >= 100 * 1024) {\n return BIG_FILE_MSG;\n }\n\n try {\n return decodeURIComponent(fileContents);\n } catch (e) {\n return BINARY_CONTENT_MSG;\n }\n })\n .catch(handleError);\n};\n\nmodule.exports = {\n getFileContents,\n};\n\n```\n\n## `index.js`\n\n```js\nconst authentication = require('./authentication');\nconst { includeBearerToken } = require('./before-handlers');\nconst hydrators = require('./hydrators');\n\nconst folder = require('./resources/folder');\nconst file = require('./resources/file');\nconst createTextFile = require('./creates/text-file');\n\n// We can roll up all our behaviors in an App.\nconst App = {\n // This is just shorthand to reference the installed dependencies you have. Zapier will\n // need to know these before we can upload\n version: require('./package.json').version,\n platformVersion: require('zapier-platform-core').version,\n\n authentication,\n\n hydrators,\n\n // Ordered list of functions to pass the request object through before\n // sending it. Here we register one function that will set the auth header.\n beforeRequest: [includeBearerToken],\n\n afterResponse: [],\n\n /* Register the two resources for this app. Each resource defines the `list`,\n * `search`, and `create` properties, allowing Zapier to automatically generate\n * a trigger, search, and a create for each one.\n */\n resources: {\n [folder.key]: folder,\n [file.key]: file,\n },\n\n triggers: {},\n\n searches: {},\n\n /* In addition to the default create from the file resource, we also want to\n * allow users to create plain text files, so we register that create here.\n */\n creates: {\n [createTextFile.key]: createTextFile,\n },\n};\n\nmodule.exports = App;\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"zapier-platform-example-app-onedrive\",\n \"version\": \"1.0.0\",\n \"description\": \"An example app for the Zapier platform. Implements part of the OneDrive API\",\n \"repository\": \"zapier/zapier-platform-example-app-onedrive\",\n \"homepage\": \"https://zapier.com/\",\n \"author\": \"Zapier <partners@zapier.com>\",\n \"license\": \"BSD-3-Clause\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"lint\": \"node_modules/.bin/eslint .\",\n \"posttest\": \"npm run lint\",\n \"test\": \"mocha --recursive --timeout 25000\",\n \"coverage\": \"istanbul cover _mocha -- --recursive --timeout 25000\"\n },\n \"engines\": {\n \"node\": \">=6.10.2\",\n \"npm\": \">=3.0.0\"\n },\n \"dependencies\": {\n \"async\": \"2.4.1\",\n \"content-disposition\": \"0.5.2\",\n \"lodash\": \"4.17.23\",\n \"node-fetch\": \"1.7.1\",\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"eslint\": \"3.19.0\",\n \"istanbul\": \"0.4.5\",\n \"mocha\": \"3.2.0\",\n \"should\": \"11.2.1\"\n },\n \"private\": true\n}\n\n```\n\n## `resources/base-item.js`\n\n```js\n'use strict';\n\n//\n// This is what file and folder use as a \"base\"\n//\n\nconst _ = require('lodash');\nconst fetch = require('node-fetch');\n\nconst utils = require('../utils');\nconst hydrators = require('../hydrators');\nconst parseResponse = utils.parseResponse;\nconst handleError = utils.handleError;\nconst cleanupPaths = utils.cleanupPaths;\nconst { BASE_ITEM_URL } = require('../constants');\n\nconst getItem = (itemType, z, bundle) => {\n const options = {\n url: `${BASE_ITEM_URL}/me/drive/items/${bundle.inputData.id}`,\n };\n return z\n .request(options)\n .then(_.partial(parseResponse, z, itemType))\n .then((item) => cleanupPaths([item])[0])\n .then((item) => {\n if (item.file) {\n item.fileContents = z.dehydrate(hydrators.getFileContents, {\n id: item.id,\n });\n }\n\n return item;\n })\n .catch(handleError);\n};\n\nconst listItems = (itemType, z, bundle) => {\n let folder = bundle.inputData.folder || '';\n\n if (folder) {\n folder = `:${encodeURIComponent(folder)}:`; // OneDrive's URL format\n }\n\n const options = {\n url: `${BASE_ITEM_URL}/me/drive/root${folder}/children`,\n };\n\n return z\n .request(options)\n .then(_.partial(parseResponse, z, itemType))\n .then(cleanupPaths)\n .then((items) => {\n items.forEach((item) => {\n if (item.file) {\n item.fileContents = z.dehydrate(hydrators.getFileContents, {\n id: item.id,\n });\n }\n });\n\n return items;\n })\n .catch(handleError);\n};\n\nconst searchItem = (itemType, z, bundle) => {\n let folder = bundle.inputData.folder || '';\n\n if (folder) {\n folder = `:${encodeURIComponent(folder)}:`; // OneDrive's URL format\n }\n\n const options = {\n url: `${BASE_ITEM_URL}/me/drive/root${folder}/search(q='${encodeURIComponent(\n bundle.inputData.name,\n )}')`,\n };\n\n return z\n .request(options)\n .then(_.partial(parseResponse, z, itemType))\n .then(cleanupPaths)\n .catch(handleError);\n};\n\n// Note this only works for files, but is here so creates/text-file can reuse it\nconst handleCreateWithSession = (\n z,\n bundle,\n fileContents,\n fileSize,\n fileContentType,\n folder,\n name,\n) => {\n if (folder) {\n folder = encodeURIComponent(folder);\n }\n\n name = encodeURIComponent(name);\n\n return z\n .request({\n url: `${BASE_ITEM_URL}/me/drive/root:${folder}/${name}:/createUploadSession`,\n method: 'POST',\n body: {\n item: {\n '@microsoft.graph.conflictBehavior': 'rename',\n },\n },\n headers: {\n 'content-type': 'application/json',\n },\n })\n .then((response) => {\n const uploadUrl = response.data.uploadUrl;\n\n // This should work fine for files up to 60MB (https://dev.onedrive.com/items/upload_large_files.htm#upload-fragments)\n\n if (!fileContentType.includes('charset')) {\n fileContentType += '; charset=UTF-8';\n }\n\n // CODE TIP: If you define beforeRequest handlers, then end up in a\n // situation where you don't want that pre-processing, you can drop to a\n // raw `fetch` call instead of the z.request() to avoid those handlers\n return fetch(uploadUrl, {\n method: 'PUT',\n body: fileContents,\n headers: {\n 'content-type': fileContentType,\n 'content-length': fileSize,\n 'content-range': `bytes 0-${fileSize - 1}/${fileSize}`,\n },\n });\n })\n .then((response) => response.text())\n .then((content) => {\n const resourceId = z.JSON.parse(content).id;\n bundle.inputData = {\n id: resourceId,\n };\n\n return _.partial(getItem, 'file')(z, bundle);\n })\n .catch(handleError);\n};\n\nmodule.exports = {\n getItem,\n listItems,\n searchItem,\n handleCreateWithSession,\n};\n\n```\n\n## `resources/file.js`\n\n```js\n'use strict';\n\nconst _ = require('lodash');\n\nconst utils = require('../utils');\nconst handleError = utils.handleError;\nconst getFileDetailsFromRequest = utils.getFileDetailsFromRequest;\nconst baseItem = require('./base-item');\n\nconst getFile = _.partial(baseItem.getItem, 'file');\n\nconst listFiles = _.partial(baseItem.listItems, 'file');\n\nconst createFile = (z, bundle) => {\n const folder = bundle.inputData.folder || '';\n // NOTE: `file` is really a URL like \"https://zapier.com/engine/hydrate/<unique_id>/.blahblahblah:blah:blah/\"\n const file = bundle.inputData.file;\n\n return getFileDetailsFromRequest(file)\n .then((fileDetails) => {\n const name =\n bundle.inputData.name || fileDetails.filename || 'unnamedfile.unknown';\n\n return baseItem.handleCreateWithSession(\n z,\n bundle,\n fileDetails.content,\n fileDetails.size,\n fileDetails.contentType,\n folder,\n name,\n );\n })\n .catch(handleError);\n};\n\nconst searchFile = _.partial(baseItem.searchItem, 'file');\n\nmodule.exports = {\n key: 'file',\n noun: 'File',\n\n get: {\n display: {\n label: 'Get File',\n description: 'Gets a file.',\n },\n operation: {\n inputFields: [\n {\n key: 'id',\n required: true,\n },\n ],\n perform: getFile,\n },\n },\n\n // Will become a trigger on the app. Key will be `fileList`\n list: {\n display: {\n label: 'New File',\n description: 'Triggers when a new file is added in a folder.',\n },\n operation: {\n inputFields: [\n {\n key: 'folder',\n type: 'string',\n label: 'Folder',\n required: false,\n dynamic: 'folderList._path.name',\n helpText:\n 'Folder where to look for the file. Keep clicking the dropdown to go inside folders. Defaults to the top-level folder if left blank.',\n },\n ],\n perform: listFiles,\n },\n },\n\n // Will become a create on the app. Key will be `fileCreate`\n create: {\n display: {\n label: 'Upload File',\n description: 'Upload an existing file or attachment.',\n },\n operation: {\n inputFields: [\n {\n key: 'folder',\n type: 'string',\n label: 'Folder',\n required: false,\n dynamic: 'folderList._path.name',\n helpText:\n 'Folder where to place the file. Keep clicking the dropdown to go inside folders. Defaults to the top-level folder if left blank.',\n },\n {\n key: 'file',\n type: 'file',\n label: 'File',\n required: true,\n helpText:\n 'Must be a file object from another service (or some text or URL).',\n },\n {\n key: 'name',\n type: 'string',\n label: 'File Name',\n required: false,\n helpText:\n 'By default, we use the same name and extension as the original file.',\n },\n ],\n perform: createFile,\n },\n },\n\n // Will become a search on the app. Key will be `fileSearch`\n search: {\n display: {\n label: 'Find File',\n description: 'Finds a file by name.',\n },\n operation: {\n inputFields: [\n {\n key: 'folder',\n type: 'string',\n label: 'Folder',\n required: false,\n dynamic: 'folderList._path.name',\n helpText:\n 'Folder where to look for the file. Keep clicking the dropdown to go inside folders. Defaults to the top-level folder if left blank.',\n },\n {\n key: 'name',\n required: true,\n type: 'string',\n },\n ],\n perform: searchFile,\n },\n },\n\n sample: {\n id: '1',\n name: 'Example.jpg',\n _path: '/Something/Example.jpg',\n _parent: '/Something',\n webUrl: 'https://example.com',\n '@microsoft.graph.downloadUrl': 'https://example.com',\n createdDateTime: '2016-09-16T03:37:04.72Z',\n lastModifiedDateTime: '2016-09-16T03:37:04.72Z',\n },\n\n outputFields: [\n { key: 'id', label: 'ID' },\n { key: 'name', label: 'File Name' },\n { key: '_path', label: 'File Path' },\n { key: '_parent', label: 'Folder' },\n { key: 'webUrl', label: 'URL' },\n { key: '@microsoft.graph.downloadUrl', label: 'Download URL' },\n ],\n};\n\n```\n\n## `resources/folder.js`\n\n```js\n'use strict';\n\nconst _ = require('lodash');\n\nconst utils = require('../utils');\nconst parseResponse = utils.parseResponse;\nconst handleError = utils.handleError;\nconst cleanupPaths = utils.cleanupPaths;\nconst extractParentsFromPath = utils.extractParentsFromPath;\nconst { BASE_ITEM_URL } = require('../constants');\nconst baseItem = require('./base-item');\n\nconst getFolder = _.partial(baseItem.getItem, 'folder');\n\nconst listFolders = (z, bundle) => {\n return baseItem.listItems('folder', z, bundle).then((results) => {\n // Add parents when being called in the context of populating a dynamic dropdown (prefill).\n // This allows users to \"navigate back\" to previous dirs in the Zap Editor\n if (bundle.meta.prefill && bundle.inputData.folder) {\n const parents = extractParentsFromPath(bundle.inputData.folder);\n parents.forEach((result) => results.unshift(result));\n }\n\n return results;\n });\n};\n\nconst createFolder = (z, bundle) => {\n let folder = bundle.inputData.folder || '';\n\n if (folder) {\n folder = `:${encodeURIComponent(folder)}:`; // OneDrive URI format\n }\n\n return z\n .request({\n url: `${BASE_ITEM_URL}/me/drive/root${folder}/children`,\n method: 'POST',\n body: {\n name: bundle.inputData.name,\n folder: {}, // This tells OneDrive it's a folder (https://dev.onedrive.com/items/create.htm#example)\n '@microsoft.graph.conflictBehavior': 'rename',\n },\n headers: {\n 'content-type': 'application/json',\n },\n })\n .then(_.partial(parseResponse, z, 'folder'))\n .then(cleanupPaths)\n .catch(handleError);\n};\n\nconst searchFolder = _.partial(baseItem.searchItem, 'folder');\n\nmodule.exports = {\n key: 'folder',\n noun: 'Folder',\n\n get: {\n display: {\n label: 'Get Folder',\n description: 'Gets a folder.',\n },\n operation: {\n inputFields: [\n {\n key: 'id',\n required: true,\n },\n ],\n perform: getFolder,\n },\n },\n\n // Will become a trigger on the app. Key will be `folderList`\n list: {\n display: {\n label: 'New Folder',\n description: 'Triggers when a new folder is added.',\n },\n operation: {\n inputFields: [\n {\n key: 'folder',\n type: 'string',\n label: 'Folder',\n required: false,\n // As mentioned above, triggers genereated from resources follow a\n // format of `<resource.key>List`, so that is what we use in all the dynamic dropdowns\n dynamic: 'folderList._path.name',\n helpText:\n 'Folder where to look for the folder. Keep clicking the dropdown to go inside folders. Defaults to the top-level folder if left blank.',\n },\n ],\n perform: listFolders,\n },\n },\n\n // Will become a create on the app. Key will be `folderCreate`\n create: {\n display: {\n label: 'Create Folder',\n description: 'Creates a new folder.',\n },\n operation: {\n inputFields: [\n {\n key: 'folder',\n type: 'string',\n label: 'Folder',\n required: false,\n dynamic: 'folderList._path.name',\n helpText:\n 'Folder where to create the folder. Keep clicking the dropdown to go inside folders. Defaults to the top-level folder if left blank.',\n },\n {\n key: 'name',\n required: true,\n type: 'string',\n },\n ],\n perform: createFolder,\n },\n },\n\n // Will become a search on the app. Key will be `folderSearch`\n search: {\n display: {\n label: 'Find Folder',\n description: 'Finds a folder by name.',\n },\n operation: {\n inputFields: [\n {\n key: 'folder',\n type: 'string',\n label: 'Folder',\n required: false,\n dynamic: 'folderList._path.name',\n helpText:\n 'Folder where to look for the folder. Keep clicking the dropdown to go inside folders. Defaults to the top-level folder if left blank.',\n },\n {\n key: 'name',\n required: true,\n type: 'string',\n },\n ],\n perform: searchFolder,\n },\n },\n\n sample: {\n id: '1',\n name: 'Example',\n _path: '/Something/Example',\n _parent: '/Something',\n webUrl: 'https://example.com',\n createdDateTime: '2016-09-16T03:37:04.72Z',\n lastModifiedDateTime: '2016-09-16T03:37:04.72Z',\n },\n\n outputFields: [\n { key: 'id', label: 'ID' },\n { key: 'name', label: 'Folder Name' },\n { key: '_path', label: 'Folder Path' },\n { key: '_parent', label: 'Parent Folder' },\n { key: 'webUrl', label: 'URL' },\n ],\n};\n\n```\n\n## `test/authentication.js`\n\n```js\nrequire('should');\n\nconst zapier = require('zapier-platform-core');\n\nconst testUtils = require('./test-utils');\nconst App = require('../index');\nconst appTester = zapier.createAppTester(App);\n\ndescribe('Authentication', () => {\n before(testUtils.globalBeforeSetup);\n\n it('should refresh auth', (done) => {\n const bundle = {\n authData: {\n access_token: process.env.ACCESS_TOKEN,\n refresh_token: process.env.REFRESH_TOKEN,\n accountType: 'personal',\n },\n };\n\n appTester(App.authentication.oauth2Config.refreshAccessToken, bundle)\n .then((result) => {\n result.should.have.property('access_token');\n result.should.have.property('refresh_token');\n done();\n })\n .catch(done);\n });\n\n it('should test auth', (done) => {\n const bundle = {\n authData: {\n access_token: process.env.ACCESS_TOKEN,\n refresh_token: process.env.REFRESH_TOKEN,\n accountType: 'personal',\n },\n inputData: {\n accountType: 'personal',\n },\n };\n\n appTester(App.authentication.test, bundle)\n .then((result) => {\n result.should.have.property('userPrincipalName');\n done();\n })\n .catch(done);\n });\n\n it('should generate an authorize URL', (done) => {\n const bundle = {\n // When an app runs on zapier.com, these will be generated by Zapier and\n // passed to your app in the bundle. For the purpose of this test, we\n // create a bundle with dummy values to ensure our function works.\n inputData: {\n state: '4444',\n redirect_uri: 'https://zapier.com/',\n accountType: 'personal',\n },\n environment: {\n CLIENT_ID: '1234',\n CLIENT_SECRET: 'asdf',\n },\n };\n\n appTester(App.authentication.oauth2Config.authorizeUrl, bundle)\n .then((authorizeUrl) => {\n authorizeUrl.should.eql(\n 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=1234&redirect_uri=http%3A%2F%2Fzapier.com%2F&response_type=code&state=4444',\n );\n done();\n })\n .catch(done);\n });\n});\n\n```\n\n## `test/creates/text-file.js`\n\n```js\n'use strict';\n\nrequire('should');\n\nconst zapier = require('zapier-platform-core');\n\nconst testUtils = require('../test-utils');\nconst App = require('../../index');\nconst appTester = zapier.createAppTester(App);\n\nconst TEST_RESOURCES = testUtils.TEST_RESOURCES;\n\ndescribe('Create Text File', () => {\n before(testUtils.globalBeforeSetup);\n\n it('should create a new text file in the root dir', (done) => {\n const file = 'Sample content';\n const name = `Test-${new Date().getTime()}`;\n\n const bundle = {\n authData: {\n access_token: process.env.ACCESS_TOKEN,\n refresh_token: process.env.REFRESH_TOKEN,\n accountType: 'personal',\n },\n inputData: {\n folder: '',\n file,\n name,\n },\n };\n\n appTester(App.creates.textFile.operation.perform, bundle)\n .then((result) => {\n result.should.have.property('id');\n result.should.have.property('file');\n result.should.not.have.property('folder');\n result.name.should.containEql(name);\n result.name.should.containEql('.txt');\n result.name.should.not.containEql('.txt.txt');\n result._parent.should.eql('');\n result._path.should.containEql(`/${name}`);\n done();\n })\n .catch(done);\n });\n\n it('should create a text file with a unicode name and contents', (done) => {\n const file = 'Ohweeeeee®™¥¶‰÷!!!!!!!!!!!';\n const name = `Test-ç€is-æ-${new Date().getTime()}.txt`;\n\n const bundle = {\n authData: {\n access_token: process.env.ACCESS_TOKEN,\n refresh_token: process.env.REFRESH_TOKEN,\n accountType: 'personal',\n },\n inputData: {\n folder: TEST_RESOURCES.folder.path,\n name,\n file,\n },\n };\n\n appTester(App.creates.textFile.operation.perform, bundle)\n .then((result) => {\n result.should.have.property('id');\n result.should.have.property('file');\n result.should.not.have.property('folder');\n result.name.should.containEql(name);\n result.name.should.containEql('.txt');\n result.name.should.not.containEql('.txt.txt');\n result._parent.should.eql(TEST_RESOURCES.folder.parent);\n result._path.should.containEql(`${TEST_RESOURCES.folder.path}/${name}`);\n done();\n })\n .catch(done);\n });\n\n it('should create a new text file in the root dir, renaming it, because another one exists', (done) => {\n const file = 'Sample content';\n const name = 'boom';\n\n const bundle = {\n authData: {\n access_token: process.env.ACCESS_TOKEN,\n refresh_token: process.env.REFRESH_TOKEN,\n accountType: 'personal',\n },\n inputData: {\n folder: '',\n file,\n name,\n },\n };\n\n appTester(App.creates.textFile.operation.perform, bundle)\n .then((result) => {\n result.should.have.property('id');\n result.should.have.property('file');\n result.should.not.have.property('folder');\n result.name.should.containEql(`${name} `);\n result.name.should.containEql('.txt');\n result.name.should.not.containEql('.txt.txt');\n result.name.should.not.containEql(`${name}.txt`);\n result._parent.should.eql('');\n result._path.should.containEql(`/${name} `);\n done();\n })\n .catch(done);\n });\n});\n\n```\n\n## `test/hydrators.js`\n\n```js\nrequire('should');\n\nconst zapier = require('zapier-platform-core');\n\nconst testUtils = require('./test-utils');\nconst App = require('../index');\nconst appTester = zapier.createAppTester(App);\n\nconst TEST_RESOURCES = testUtils.TEST_RESOURCES;\n\ndescribe('Hydrators', () => {\n before(testUtils.globalBeforeSetup);\n\n it('should get file contents', (done) => {\n const bundle = {\n authData: {\n access_token: process.env.ACCESS_TOKEN,\n },\n inputData: {\n id: TEST_RESOURCES.root.id,\n },\n };\n\n appTester(App.hydrators.getFileContents, bundle)\n .then((fileContents) => {\n fileContents.length.should.above(0);\n done();\n })\n .catch(done);\n });\n\n it('should get unicode file contents', (done) => {\n // CODE TIP: Hydrating files often involves touching the raw bytes (and\n // handling the file names), so it's a good idea to test different edge cases\n done();\n });\n\n it('should not get file contents for big files', (done) => {\n // An example edge case that would be worth testing\n done();\n });\n\n it('should not get file contents for binary files', (done) => {\n // An example edge case that would be worth testing\n done();\n });\n});\n\n```\n\n## `test/resources/file.js`\n\n```js\n'use strict';\n\nrequire('should');\n\nconst zapier = require('zapier-platform-core');\n\nconst testUtils = require('../test-utils');\nconst App = require('../../index');\nconst appTester = zapier.createAppTester(App);\n\nconst TEST_RESOURCES = testUtils.TEST_RESOURCES;\n\ndescribe('File Resource', () => {\n before(testUtils.globalBeforeSetup);\n\n it('should get an existing file in the root folder', (done) => {\n const bundle = {\n authData: {\n access_token: process.env.ACCESS_TOKEN,\n refresh_token: process.env.REFRESH_TOKEN,\n accountType: 'personal',\n },\n inputData: {\n id: TEST_RESOURCES.root.id,\n },\n };\n\n appTester(App.resources.file.get.operation.perform, bundle)\n .then((result) => {\n result.should.have.property('id');\n result.should.have.property('file');\n result.should.not.have.property('folder');\n result.name.should.eql(TEST_RESOURCES.root.name);\n result._path.should.eql(TEST_RESOURCES.root.path);\n result._parent.should.eql(TEST_RESOURCES.root.parent);\n done();\n })\n .catch(done);\n });\n\n it('should get an existing file in a child folder', (done) => {\n // An example scenario that could be worth testing if the HTTP request for\n // a child folder is sufficiently different from a root folder\n done();\n });\n\n it('should list files in root dir', (done) => {\n const bundle = {\n authData: {\n access_token: process.env.ACCESS_TOKEN,\n refresh_token: process.env.REFRESH_TOKEN,\n accountType: 'personal',\n },\n inputData: {\n folder: '',\n },\n };\n\n appTester(App.resources.file.list.operation.perform, bundle)\n .then((results) => {\n results.length.should.above(0);\n results.forEach((result) => {\n result.should.have.property('id');\n result.should.have.property('file');\n result.should.not.have.property('folder');\n });\n done();\n })\n .catch(done);\n });\n\n it('should not miss any fields from the sample', (done) => {\n const bundle = {\n authData: {\n access_token: process.env.ACCESS_TOKEN,\n refresh_token: process.env.REFRESH_TOKEN,\n accountType: 'personal',\n },\n inputData: {\n folder: '',\n },\n };\n\n appTester(App.resources.file.list.operation.perform, bundle)\n .then((results) => {\n results.length.should.above(0);\n results.forEach((result) => {\n result.should.have.property('id');\n result.should.have.property('file');\n result.should.not.have.property('folder');\n });\n const file = results[0];\n const sampleKeys = Object.keys(App.resources.file.sample);\n sampleKeys.forEach((sampleKey) => file[sampleKey].should.eql(true));\n done();\n })\n .catch(done);\n });\n\n it('should upload a new file in the root dir', (done) => {\n const file =\n 'https://cdn.zapier.com/storage/files/f6679cf77afeaf6b8426de8d7b9642fc.pdf';\n const name = `Test-${new Date().getTime()}-ç€is-æ.pdf`;\n\n const bundle = {\n authData: {\n access_token: process.env.ACCESS_TOKEN,\n refresh_token: process.env.REFRESH_TOKEN,\n accountType: 'personal',\n },\n inputData: {\n folder: '',\n file,\n name,\n },\n };\n\n appTester(App.resources.file.create.operation.perform, bundle)\n .then((result) => {\n result.should.have.property('id');\n result.should.have.property('file');\n result.should.not.have.property('folder');\n result.name.should.containEql(name);\n result._parent.should.eql('');\n result._path.should.containEql(`/${name}`);\n done();\n })\n .catch(done);\n });\n\n it('should upload an utf8-named file', (done) => {\n // CODE TIP: It's a good idea to write multiple tests cases around creates\n // to verify some of the common edges:\n // * Non-ascii data\n // * Records associated with the right relationships (i.e. a file in a folder, an owner of a lead)\n // * Critical defaults work as expected\n // * Dates & times are set correctly\n done();\n });\n\n it('should upload a new file in the root dir, renaming it, because another one exists', (done) => {\n // An example of an edge case where a naming collision in OneDrive could\n // cause an overwrite or an auto-renaming of the file, so we want to test\n // and make sure we get the behavior we want (auto-renaming)\n done();\n });\n\n it('should find a file in the root dir', (done) => {\n const bundle = {\n authData: {\n access_token: process.env.ACCESS_TOKEN,\n refresh_token: process.env.REFRESH_TOKEN,\n accountType: 'personal',\n },\n inputData: {\n folder: '',\n name: 'sample',\n },\n };\n\n appTester(App.resources.file.search.operation.perform, bundle)\n .then((results) => {\n results.length.should.above(0);\n results[0].should.have.property('id');\n results[0].should.have.property('file');\n results[0].should.not.have.property('folder');\n results[0].name.should.containEql('sample');\n results[0]._parent.should.eql('');\n results[0]._path.should.containEql('/sample');\n done();\n })\n .catch(done);\n });\n\n it('should find a file in a child dir', (done) => {\n // An example scenario that could be worth testing if the HTTP request for\n // a child folder is sufficiently different from a root folder\n done();\n });\n\n it('should find a unicode file in a child dir', (done) => {\n // CODE TIP: Like with creates, adding multiple tests around the common\n // edge cases of searching is a good idea\n done();\n });\n});\n\n```\n\n## `test/resources/folder.js`\n\n```js\n'use strict';\n\nrequire('should');\n\nconst zapier = require('zapier-platform-core');\n\nconst testUtils = require('../test-utils');\nconst App = require('../../index');\nconst appTester = zapier.createAppTester(App);\n\nconst TEST_RESOURCES = testUtils.TEST_RESOURCES;\n\ndescribe('Folder Resource', () => {\n before(testUtils.globalBeforeSetup);\n\n it('should get an existing root folder', (done) => {\n const bundle = {\n authData: {\n access_token: process.env.ACCESS_TOKEN,\n refresh_token: process.env.REFRESH_TOKEN,\n accountType: 'personal',\n },\n inputData: {\n id: TEST_RESOURCES.folder.id,\n },\n };\n\n appTester(App.resources.folder.get.operation.perform, bundle)\n .then((result) => {\n result.should.have.property('id');\n result.should.have.property('folder');\n result.should.not.have.property('file');\n result.name.should.eql(TEST_RESOURCES.root.name);\n result._path.should.eql(TEST_RESOURCES.root.path);\n result._parent.should.eql(TEST_RESOURCES.root.parent);\n done();\n })\n .catch(done);\n });\n\n it('should get an existing child folder', (done) => {\n // An example scenario that could be worth testing if the HTTP request for\n // a child folder is sufficiently different from a root folder\n done();\n });\n\n it('should list folders in root dir', (done) => {\n const bundle = {\n authData: {\n access_token: process.env.ACCESS_TOKEN,\n refresh_token: process.env.REFRESH_TOKEN,\n accountType: 'personal',\n },\n inputData: {\n folder: '',\n },\n meta: {\n prefill: false,\n },\n };\n\n appTester(App.resources.folder.list.operation.perform, bundle)\n .then((results) => {\n results.length.should.above(0);\n results.forEach((result) => {\n result.should.have.property('id');\n result.should.have.property('folder');\n result.should.not.have.property('file');\n });\n done();\n })\n .catch(done);\n });\n\n it('should list folders without parents on no prefill', (done) => {\n // CODE TIP: When reusing a list operation to power a trigger and a\n // dynmaic dropdown (prefill), it's a good idea to test both scenarios if the\n // output from the operation varies between the two contexts\n const bundle = {\n authData: {\n access_token: process.env.ACCESS_TOKEN,\n refresh_token: process.env.REFRESH_TOKEN,\n accountType: 'personal',\n },\n inputData: {\n folder: TEST_RESOURCES.childFolder.path,\n },\n meta: {\n prefill: false,\n },\n };\n\n appTester(App.resources.folder.list.operation.perform, bundle)\n .then((results) => {\n results.length.should.above(0);\n\n let foundParents = false;\n\n results.forEach((result) => {\n result.should.have.property('id');\n result.should.have.property('folder');\n result.should.not.have.property('file');\n if (result.id < 0) {\n foundParents = true;\n }\n });\n\n foundParents.should.eql(false);\n done();\n })\n .catch(done);\n });\n\n it('should list folders with parents on prefill', (done) => {\n const bundle = {\n authData: {\n access_token: process.env.ACCESS_TOKEN,\n refresh_token: process.env.REFRESH_TOKEN,\n accountType: 'personal',\n },\n inputData: {\n folder: TEST_RESOURCES.childFolder.path,\n },\n meta: {\n prefill: true,\n },\n };\n\n appTester(App.resources.folder.list.operation.perform, bundle)\n .then((results) => {\n results.length.should.above(0);\n\n let foundParents = false;\n\n results.forEach((result) => {\n result.should.have.property('id');\n result.should.have.property('folder');\n result.should.not.have.property('file');\n if (result.id < 0) {\n foundParents = true;\n }\n });\n\n foundParents.should.eql(true);\n done();\n })\n .catch(done);\n });\n\n it('should not miss any fields from the sample', (done) => {\n const bundle = {\n authData: {\n access_token: process.env.ACCESS_TOKEN,\n refresh_token: process.env.REFRESH_TOKEN,\n accountType: 'personal',\n },\n inputData: {\n folder: '',\n },\n meta: {\n prefill: false,\n },\n };\n\n appTester(App.resources.folder.list.operation.perform, bundle)\n .then((results) => {\n results.length.should.above(0);\n results.forEach((result) => {\n result.should.have.property('id');\n result.should.have.property('folder');\n result.should.not.have.property('file');\n });\n const folder = results[0];\n const sampleKeys = Object.keys(App.resources.folder.sample);\n sampleKeys.forEach((sampleKey) => folder[sampleKey].should.eql(true));\n done();\n })\n .catch(done);\n });\n\n it('should create a new folder in the root dir', (done) => {\n const name = `Test-${new Date().getTime()}`;\n\n const bundle = {\n authData: {\n access_token: process.env.ACCESS_TOKEN,\n refresh_token: process.env.REFRESH_TOKEN,\n accountType: 'personal',\n },\n inputData: {\n folder: '',\n name,\n },\n };\n\n appTester(App.resources.folder.create.operation.perform, bundle)\n .then((result) => {\n result.should.have.property('id');\n result.should.have.property('folder');\n result.should.not.have.property('file');\n result.name.should.containEql(name);\n result._parent.should.eql('');\n result._path.should.containEql(`/${name}`);\n done();\n })\n .catch(done);\n });\n\n it('should create a new folder in a child dir', (done) => {\n // An example scenario that could be worth testing if the HTTP request for\n // a child folder is sufficiently different from a root folder\n done();\n });\n\n it('should find a folder in the root dir', (done) => {\n const bundle = {\n authData: {\n access_token: process.env.ACCESS_TOKEN,\n refresh_token: process.env.REFRESH_TOKEN,\n accountType: 'personal',\n },\n inputData: {\n folder: '',\n name: 'Documents',\n },\n };\n\n appTester(App.resources.folder.search.operation.perform, bundle)\n .then((results) => {\n results.length.should.above(0);\n results[0].should.have.property('id');\n results[0].should.have.property('folder');\n results[0].should.not.have.property('file');\n results[0].name.should.containEql('Documents');\n results[0]._parent.should.eql('');\n results[0]._path.should.containEql('/Documents');\n done();\n })\n .catch(done);\n });\n\n it('should find a folder in a child dir', (done) => {\n // An example scenario that could be worth testing if the HTTP request for\n // a child folder is sufficiently different from a root folder\n done();\n });\n});\n\n```\n\n## `test/test-utils.js`\n\n```js\n'use strict';\n\nrequire('should');\n\nconst zapier = require('zapier-platform-core');\n\nconst App = require('../index');\nconst appTester = zapier.createAppTester(App);\n\nconst globalBeforeSetup = (done) => {\n zapier.tools.env.inject();\n\n if (\n !process.env.CLIENT_ID ||\n !process.env.CLIENT_SECRET ||\n !process.env.REFRESH_TOKEN\n ) {\n throw new Error(\n 'Setup your .environment file (or use `export`) according to the README.',\n );\n }\n\n // ACCESS_TOKEN expires very quickly, so we get a new one per test run from REFRESH_TOKEN\n if (!process.env.ACCESS_TOKEN) {\n const bundle = {\n authData: {\n access_token: '',\n refresh_token: process.env.REFRESH_TOKEN,\n accountType: 'personal',\n },\n };\n\n appTester(App.authentication.oauth2Config.refreshAccessToken, bundle)\n .then((result) => {\n result.should.have.property('access_token');\n result.should.have.property('refresh_token');\n process.env.ACCESS_TOKEN = result.access_token;\n done();\n })\n .catch(done);\n } else {\n done();\n }\n};\n\n// Below is a set of files the app can use to test different scenarios.\n// To make the test suite run, add files to your account in the given folders,\n// then fill in the IDs of files from your account. The `id` is visible in the\n// URL when accessing the file in the browser, for example:\n// URL: https://onedrive.live.com/?cid=697LD7B578EB1372&id=697LD7B578EB1372%21716\n// ID: 697LD7B578EB1372!716\nconst TEST_RESOURCES = {\n root: {\n id: '',\n name: 'sample.pdf',\n path: '/sample.pdf',\n parent: '',\n },\n nested: {\n id: '',\n name: 'test.txt',\n path: '/Documents/Testing/test.txt',\n parent: '/Documents/Testing',\n },\n\n folder: {\n id: '',\n name: 'Documents',\n path: '/Documents',\n parent: '',\n },\n childFolder: {\n id: '',\n name: 'Testing',\n path: '/Documents/Testing',\n parent: '/Documents',\n },\n};\n\nmodule.exports = {\n globalBeforeSetup,\n TEST_RESOURCES,\n};\n\n```\n\n## `test/utils.js`\n\n```js\n'use strict';\n\nrequire('should');\n\nconst utils = require('../utils');\nconst extractParentsFromPath = utils.extractParentsFromPath;\nconst getStringByteSize = utils.getStringByteSize;\n\ndescribe('Utils', () => {\n it('should extract parents from a folder path', () => {\n let parents = extractParentsFromPath('/Some/Kind of /Test');\n\n parents.length.should.eql(3);\n\n parents[0].id.should.eql(-1);\n parents[0].name.should.eql('/');\n parents[0]._path.should.eql('');\n parents[0].should.have.property('folder');\n parents[0].should.not.have.property('file');\n\n parents[1].id.should.eql(-2);\n parents[1].name.should.eql('Some');\n parents[1]._path.should.eql('/Some');\n parents[1].should.have.property('folder');\n parents[1].should.not.have.property('file');\n\n parents[2].id.should.eql(-3);\n parents[2].name.should.eql('Kind of ');\n parents[2]._path.should.eql('/Some/Kind of ');\n parents[2].should.have.property('folder');\n parents[2].should.not.have.property('file');\n\n parents = extractParentsFromPath('/Zapier');\n\n parents.length.should.eql(1);\n\n parents[0].id.should.eql(-1);\n parents[0].name.should.eql('/');\n parents[0]._path.should.eql('');\n parents[0].should.have.property('folder');\n parents[0].should.not.have.property('file');\n });\n\n it('should correctly compute the byte size of strings', () => {\n const tests = [\n {\n string: 'asd',\n expected: 3,\n },\n {\n string: '@€£¶‰dfg',\n expected: 14,\n },\n {\n string: '÷¶[]÷d()ß-°ú',\n expected: 18,\n },\n {\n string: 'ç€is-æ',\n expected: 10,\n },\n ];\n\n tests.forEach((test) =>\n getStringByteSize(test.string).should.eql(test.expected),\n );\n });\n});\n\n```\n\n## `utils.js`\n\n```js\n'use strict';\n\nconst _ = require('lodash');\nconst fetch = require('node-fetch');\nconst contentDisposition = require('content-disposition');\n\n// CODE TIP: This function is used to process the response of several endpoints\n// on the OneDrive API. We intentionally don't set it up as an `afterResposne`\n// handler because not *all* calls need it (i.e. the auth test and file create),\n// so we break it out and share the code this way instead.\nconst parseResponse = (z, type, response) => {\n let results = [];\n\n if (response.status >= 200 && response.status < 300) {\n results = response.data;\n\n // OneDrive puts the contents of lists inside .value property\n if (!_.isArray(results) && _.isArray(results.value)) {\n results = results.value;\n }\n } else {\n throw new z.errors.Error(response.content, null, response.status);\n }\n\n // Only return files or folders, according to type\n if (_.isArray(results)) {\n results = results.filter((result) => result[type]);\n } else {\n if (!results[type]) {\n results = {};\n }\n }\n\n return results;\n};\n\nconst handleError = (error) => {\n if (typeof error === 'string') {\n throw new Error(error);\n }\n\n throw error;\n};\n\nconst extractParentsFromPath = (path) => {\n const parts = path.split('/');\n const results = [];\n\n parts.splice(parts.length - 1); // Last is the current directory, so we remove it\n\n let i = parts.length - 1;\n\n while (parts.length > 0) {\n const name = parts.splice(i)[0];\n\n const result = {\n id: (i + 1) * -1,\n name: name === '' ? '/' : name,\n _path: parts.join('/') + (name === '' ? name : `/${name}`),\n folder: {},\n };\n\n results.push(result);\n\n i -= 1;\n }\n\n results.reverse();\n\n return results;\n};\n\n// UX TIP: Sometimes it can be helpful to translate raw values from an API into\n// terms that end users are familiar with. In this example, OneDrive returns\n// parent and the path of a file with a '/drive/root:' that end users of OneDrive\n// never see. To help it read better in a dynamic dropdown, we clean that off\nconst cleanupPaths = (results) => {\n // We can get a single object here as well\n if (!_.isArray(results)) {\n results._parent = _.get(results, 'parentReference.path', '').replace(\n '/drive/root:',\n '',\n );\n results._path = `${results._parent}/${results.name}`;\n return results;\n }\n\n // Adds easier to reference paths, cleaning up the \"/drive/root:\" clutter\n return results.map((result) => {\n result._parent = _.get(result, 'parentReference.path', '').replace(\n '/drive/root:',\n '',\n );\n result._path = `${result._parent}/${result.name}`;\n return result;\n });\n};\n\nconst getFileDetailsFromRequest = (url) =>\n new Promise((resolve, reject) => {\n const fileDetails = {\n filename: '',\n size: 0,\n content: '',\n contentType: '',\n };\n\n fetch(url)\n .then((response) => {\n fileDetails.size = response.headers.get('content-length');\n fileDetails.contentType = response.headers.get('content-type');\n const disposition = response.headers.get('content-disposition');\n\n if (disposition) {\n fileDetails.filename =\n contentDisposition.parse(disposition).parameters.filename;\n }\n\n return response.buffer();\n })\n .then((content) => {\n fileDetails.content = content;\n\n return resolve(fileDetails);\n })\n .catch(reject);\n });\n\nconst getStringByteSize = (string) => Buffer.byteLength(string, 'utf8');\n\nmodule.exports = {\n parseResponse,\n handleError,\n extractParentsFromPath,\n cleanupPaths,\n getFileDetailsFromRequest,\n getStringByteSize,\n};\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/onedrive", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/onedrive", "section": "templates", "tags": ["example", "template"], "related": [], "meta": {"files": ["constants.js", "before-handlers.js", "hydrators.js", "index.js", "README.md", "package.json", "utils.js", ".eslintrc.json", "authentication.js", "creates/text-file.js", "test/hydrators.js", "test/utils.js", "test/test-utils.js", "test/authentication.js", "resources/folder.js", "resources/base-item.js", "resources/file.js", "test/creates/text-file.js", "test/resources/folder.js", "test/resources/file.js"], "auth": null, "pattern": "example", "local": "repos/zapier-platform/example-apps/onedrive"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:openai", "kind": "template", "key": "openai", "title": "Source template: openai", "summary": "Full example-app source (n/a / example).", "body": "# example-app `openai`\n\nAuth: `n/a` · Pattern: `example`\n\n## `README.md`\n\n```md\n# OpenAI\n\nThis Zapier integration project is generated by the `zapier-platform init` CLI command. This integration in particular is using the OpenAI API to generate responses to prompts from users. For this integration, there is a `constants.js` file that will allow you to swap out the base URL and version of the API to swap if you are using an OpenAI compatible API to get started.\n\nThese are what you normally do next:\n\n```bash\n# Install dependencies\nnpm install # or you can use yarn\n\n# Run tests\nzapier-platform test\n\n# Register the integration on Zapier if you haven't\nzapier-platform register \"App Title\"\n\n# Or you can link to an existing integration on Zapier\nzapier-platform link\n\n# Push it to Zapier\nzapier-platform push\n```\n\nFind out more on the latest docs: https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md.\n\n```\n\n## `authentication.js`\n\n```js\nconst { API_URL } = require('./constants');\n// You want to make a request to an endpoint that is either specifically designed\n// to test auth, or one that every user will have access to. eg: `/me`.\n// By returning the entire request object, you have access to the request and\n// response data for testing purposes. Your connection label can access any data\n// from the returned response using the `json.` prefix. eg: `{{json.username}}`.\nconst test = (z, bundle) => z.request({ url: `${API_URL}/me` });\n\nmodule.exports = {\n // \"custom\" is the catch-all auth type. The user supplies some info and Zapier can\n // make authenticated requests with it\n type: 'custom',\n\n // Define any input app's auth requires here. The user will be prompted to enter\n // this info when they connect their account.\n fields: [\n {\n key: 'api_key',\n label: 'API Key',\n required: true,\n helpText:\n 'Generate an API Key in your [Platform settings page](https://platform.openai.com/api-keys).',\n },\n // This field is optional and can be removed if not needed\n {\n key: 'organization_id',\n required: false,\n label: 'Organization ID',\n helpText:\n '**Optional** Only required if your OpenAI account belongs to multiple organizations. If not using OpenAI, this field will be disregarded. If your OpenAI account belongs to multiple organizations, optionally add the [Organization ID](https://platform.openai.com/account/org-settings) that this connection should use. If left blank, your [default organization](https://platform.openai.com/account/api-keys) will be used.',\n },\n ],\n\n // The test method allows Zapier to verify that the credentials a user provides\n // are valid. We'll execute this method whenever a user connects their account for\n // the first time.\n test,\n\n // This template string can access all the data returned from the auth test. If\n // you return the test object, you'll access the returned data with a label like\n // `{{json.X}}`. If you return `response.data` from your test, then your label can\n // be `{{X}}`. This can also be a function that returns a label. That function has\n // the standard args `(z, bundle)` and data returned from the test can be accessed\n // in `bundle.inputData.X`.\n connectionLabel: '{{json.email}}',\n};\n\n```\n\n## `constants.js`\n\n```js\nconst BASE_URL = 'https://api.openai.com';\nconst VERSION = 'v1';\nconst API_URL = `${BASE_URL}/${VERSION}`;\n\nconst DEFAULT_MODEL = 'gpt-4o-mini';\n\nmodule.exports = {\n API_URL,\n DEFAULT_MODEL,\n};\n\n```\n\n## `creates/chat_completion.js`\n\n```js\n/* eslint-disable camelcase */\nconst { API_URL, DEFAULT_MODEL } = require('../constants');\n\nconst sample = require('../samples/chat.json');\n\nasync function getAdvancedFields(_z, bundle) {\n if (bundle.inputData.show_advanced === true) {\n return [\n {\n key: 'info_advanced',\n type: 'copy',\n helpText:\n \"The following fields are for advanced users and should be used with caution as they may affect performance. In most cases, the default options are sufficient. If you'd like to explore these options further, you can [learn more here](https://help.zapier.com/hc/en-us/articles/22497191078797).\",\n },\n {\n key: 'developer_message',\n label: 'Developer/System Message',\n type: 'text',\n helpText:\n 'Instructions to the model that are prioritized ahead of user messages, following [chain of command](https://cdn.openai.com/spec/model-spec-2024-05-08.html#follow-the-chain-of-command).',\n },\n {\n key: 'temperature',\n label: 'Temperature',\n type: 'number',\n helpText:\n 'Higher values mean the model will take more risks. Try 0.9 for more creative applications, and 0 for ones with a well-defined answer.\\n\\nUse a decimal between 0 and 1.',\n },\n {\n key: 'max_completion_tokens',\n label: 'Maximum Length',\n type: 'integer',\n helpText: 'The maximum number of tokens for the completion.',\n },\n ];\n }\n return [];\n}\n\nasync function perform(z, bundle) {\n const {\n user_message,\n model,\n files,\n developer_message,\n temperature,\n max_completion_tokens,\n } = bundle.inputData;\n\n const developerMessage = {\n role: 'developer',\n content: [\n {\n type: 'text',\n text: developer_message || 'You are a helpful assistant.',\n },\n ],\n };\n\n const userMessage = {\n role: 'user',\n content: [\n {\n type: 'text',\n text: user_message,\n },\n ...(files\n ? files.map((file) => ({\n type: 'image_url',\n image_url: {\n url: file,\n },\n }))\n : []),\n ],\n };\n\n const messages = [developerMessage, userMessage];\n\n const response = await z.request({\n url: `${API_URL}/chat/completions`,\n method: 'POST',\n body: JSON.stringify({\n model,\n messages,\n temperature,\n max_completion_tokens,\n }),\n });\n return response.data;\n}\n\nmodule.exports = {\n key: 'chat_completion',\n noun: 'Chat',\n display: {\n label: 'Chat Completion',\n description: 'Sends a Chat to OpenAI and generates a Completion.',\n },\n operation: {\n perform,\n inputFields: [\n {\n key: 'info_data_usage',\n type: 'copy',\n helpText:\n \"Data sent to OpenAI through this Zap is via an API. Under OpenAI's [API data usage policy](https://openai.com/policies/api-data-usage-policies), OpenAI will not use API-submitted data to train or improve their models unless you explicitly decide to share your data with them for that purpose (such as by opting in). For more information, please review OpenAI's article about [when/how data may be used to improve model performance](https://help.openai.com/en/articles/5722486-how-your-data-is-used-to-improve-model-performance).\",\n },\n {\n key: 'user_message',\n label: 'User Message',\n type: 'text',\n helpText:\n \"Instructions that request some output from the model. Similar to messages you'd type in [ChatGPT](https://chatgpt.com) as an end user.\",\n required: true,\n },\n {\n key: 'files',\n label: 'Images',\n type: 'file',\n helpText: 'Images to include along with your message.',\n list: true,\n },\n {\n key: 'model',\n label: 'Model',\n type: 'string',\n required: true,\n default: DEFAULT_MODEL, // Optional to default to a specific model for most users\n dynamic: 'list_models.id.name',\n altersDynamicFields: false,\n },\n {\n key: 'show_advanced',\n label: 'Show Advanced Options',\n type: 'boolean',\n default: 'false',\n altersDynamicFields: true,\n },\n getAdvancedFields,\n ],\n // Rename some of the output fields to be more descriptive for a user\n outputFields: [\n { key: 'id', type: 'string', label: 'Completion ID' },\n { key: 'model', type: 'string', label: 'Model' },\n {\n key: 'usage__prompt_tokens',\n type: 'number',\n label: 'Usage: Prompt Tokens',\n },\n {\n key: 'usage__completion_tokens',\n type: 'number',\n label: 'Usage: Completion Tokens',\n },\n {\n key: 'usage__total_tokens',\n type: 'number',\n label: 'Usage: Total Tokens',\n },\n ],\n sample,\n },\n};\n\n```\n\n## `creates/index.js`\n\n```js\n/* eslint-disable camelcase */\nconst chat_completion = require('./chat_completion');\n\n// If you add a new create, make sure it is exported here to display in the Zapier Editor\nmodule.exports = {\n [chat_completion.key]: chat_completion,\n};\n\n```\n\n## `dynamic_dropdowns/index.js`\n\n```js\n/* eslint-disable camelcase */\nconst list_models = require('./list_models.js');\n\n// If you add a new Dynamic Dropdown, make sure it is exported here to display in the Zapier Editor\nmodule.exports = {\n [list_models.key]: list_models,\n};\n\n```\n\n## `dynamic_dropdowns/list_models.js`\n\n```js\nconst { API_URL } = require('../constants');\n\nconst perform = async (z, bundle) => {\n const response = await z.request({ url: `${API_URL}/models` });\n\n const responseData = response.data;\n\n return responseData.data.map((model) => ({\n id: model.id,\n name: model.id,\n }));\n};\n\nmodule.exports = {\n key: 'list_models',\n noun: 'Model',\n display: {\n label: 'List of Models',\n description:\n 'This is a hidden trigger, and is used in a Dynamic Dropdown of another trigger.',\n hidden: true,\n },\n operation: { perform },\n};\n\n```\n\n## `index.js`\n\n```js\n/* eslint-disable camelcase */\nconst authentication = require('./authentication');\nconst middleware = require('./middleware');\nconst dynamic_dropdowns = require('./dynamic_dropdowns');\nconst creates = require('./creates');\n\nmodule.exports = {\n // This is just shorthand to reference the installed dependencies you have.\n // Zapier will need to know these before we can upload.\n version: require('./package.json').version,\n platformVersion: require('zapier-platform-core').version,\n\n authentication,\n\n beforeRequest: [...middleware.befores],\n\n afterResponse: [...middleware.afters],\n\n // If you want your trigger to show up, you better include it here!\n triggers: {\n ...dynamic_dropdowns,\n },\n\n // If you want your searches to show up, you better include it here!\n searches: {},\n\n // If you want your creates to show up, you better include it here!\n creates: {\n ...creates,\n },\n\n resources: {},\n};\n\n```\n\n## `middleware.js`\n\n```js\n/* eslint-disable camelcase */\n// This function runs after every outbound request. You can use it to check for\n// errors or modify the response. You can have as many as you need. They'll need\n// to each be registered in your index.js file.\nconst handleBadResponses = (response, z, bundle) => {\n if (response.data.error) {\n throw new z.errors.Error(\n response.data.error.message,\n response.data.error.code,\n response.status,\n );\n }\n\n return response;\n};\n\nconst includeOrgId = (request, z, bundle) => {\n const { organization_id } = bundle.authData;\n if (organization_id) {\n request.headers['OpenAI-Organization'] = organization_id;\n }\n return request;\n};\n\n// This function runs before every outbound request. You can have as many as you\n// need. They'll need to each be registered in your index.js file.\nconst includeApiKey = (request, z, bundle) => {\n const { api_key } = bundle.authData;\n if (api_key) {\n // Use these lines to include the API key in the querystring\n // request.params = request.params || {};\n // request.params.api_key = api_key;\n\n // If you want to include the API key in the header:\n request.headers.Authorization = `Bearer ${api_key}`;\n }\n\n return request;\n};\n\nconst jsonHeaders = (request) => {\n request.headers['Content-Type'] = 'application/json';\n request.headers.Accept = 'application/json';\n return request;\n};\n\nmodule.exports = {\n befores: [includeApiKey, includeOrgId, jsonHeaders],\n afters: [handleBadResponses],\n};\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"openai\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"jest --testTimeout 10000\"\n },\n \"dependencies\": {\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"jest\": \"^25.5.3\"\n },\n \"private\": true\n}\n\n```\n\n## `samples/chat.json`\n\n```json\n{\n \"id\": \"chatcmpl-123\",\n \"object\": \"chat.completion\",\n \"created\": 1677652288,\n \"model\": \"gpt-4o-mini\",\n \"system_fingerprint\": \"fp_44709d6fcb\",\n \"choices\": [\n {\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today?\"\n },\n \"logprobs\": null,\n \"finish_reason\": \"stop\"\n }\n ],\n \"service_tier\": \"default\",\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"completion_tokens_details\": {\n \"reasoning_tokens\": 0,\n \"accepted_prediction_tokens\": 0,\n \"rejected_prediction_tokens\": 0\n }\n }\n}\n\n```\n\n## `test/authentication.test.js`\n\n```js\n/* globals describe, it, expect */\n/* eslint-disable no-undef */\n\nconst App = require('../index');\n\ndescribe('custom auth', () => {\n beforeEach(() => {\n jest.clearAllMocks();\n });\n\n it('passes authentication and returns json', async () => {\n const bundle = {\n authData: {\n api_key: 'secret',\n },\n };\n\n // Mock successful response\n const mockResponse = {\n status: 200,\n data: {\n email: 'test@example.com',\n },\n };\n\n // Mock the request client\n const mockRequest = jest.fn().mockResolvedValue(mockResponse);\n const z = {\n request: mockRequest,\n };\n\n const response = await App.authentication.test(z, bundle);\n\n expect(mockRequest).toHaveBeenCalledTimes(1);\n expect(mockRequest).toHaveBeenCalledWith({\n url: expect.stringContaining('/me'),\n });\n expect(response.status).toBe(200);\n expect(response.data).toHaveProperty('email', 'test@example.com');\n });\n\n it('fails on bad auth', async () => {\n const bundle = {\n authData: {\n api_key: 'bad',\n },\n };\n\n // Mock failed response\n const mockRequest = jest\n .fn()\n .mockRejectedValue(new Error('Incorrect API key provided'));\n const z = {\n request: mockRequest,\n };\n\n try {\n await App.authentication.test(z, bundle);\n } catch (error) {\n expect(mockRequest).toHaveBeenCalledTimes(1);\n expect(error.message).toContain('Incorrect API key provided');\n return;\n }\n throw new Error('appTester should have thrown');\n });\n});\n\n```\n\n## `test/chat_completion.test.js`\n\n```js\n/* globals describe, it, expect */\n/* eslint-disable no-undef */\n\nconst chatCompletion = require('../creates/chat_completion');\nconst { DEFAULT_MODEL } = require('../constants');\n\ndescribe('chat_completion', () => {\n beforeEach(() => {\n jest.clearAllMocks();\n });\n\n it('creates a basic chat completion', async () => {\n const bundle = {\n inputData: {\n user_message: 'Hello, how are you?',\n model: DEFAULT_MODEL,\n },\n };\n\n const mockResponse = {\n data: {\n id: 'chatcmpl-123',\n model: DEFAULT_MODEL,\n usage: {\n prompt_tokens: 20,\n completion_tokens: 15,\n total_tokens: 35,\n },\n choices: [\n {\n message: {\n content: 'I am doing well, thank you for asking!',\n },\n },\n ],\n },\n };\n\n const mockRequest = jest.fn().mockResolvedValue(mockResponse);\n const z = { request: mockRequest };\n\n const result = await chatCompletion.operation.perform(z, bundle);\n\n expect(mockRequest).toHaveBeenCalledTimes(1);\n expect(mockRequest).toHaveBeenCalledWith({\n url: expect.stringContaining('/chat/completions'),\n method: 'POST',\n body: expect.stringContaining(bundle.inputData.user_message),\n });\n\n expect(result).toEqual(mockResponse.data);\n });\n\n it('creates a chat completion with advanced options', async () => {\n const bundle = {\n inputData: {\n user_message: 'Write a story',\n model: DEFAULT_MODEL,\n developer_message: 'You are a creative writer',\n temperature: 0.9,\n max_completion_tokens: 100,\n },\n };\n\n const mockResponse = {\n data: {\n id: 'chatcmpl-456',\n model: DEFAULT_MODEL,\n usage: {\n prompt_tokens: 25,\n completion_tokens: 50,\n total_tokens: 75,\n },\n },\n };\n\n const mockRequest = jest.fn().mockResolvedValue(mockResponse);\n const z = { request: mockRequest };\n\n const result = await chatCompletion.operation.perform(z, bundle);\n\n expect(mockRequest).toHaveBeenCalledTimes(1);\n expect(mockRequest).toHaveBeenCalledWith({\n url: expect.stringContaining('/chat/completions'),\n method: 'POST',\n body: expect.stringMatching(/temperature.*0.9/),\n });\n\n expect(result).toEqual(mockResponse.data);\n });\n\n it('creates a chat completion with image', async () => {\n const bundle = {\n inputData: {\n user_message: 'Describe this image',\n model: DEFAULT_MODEL,\n files: ['https://example.com/image.jpg'],\n },\n };\n\n const mockResponse = {\n data: {\n id: 'chatcmpl-789',\n model: DEFAULT_MODEL,\n usage: {\n prompt_tokens: 30,\n completion_tokens: 20,\n total_tokens: 50,\n },\n },\n };\n\n const mockRequest = jest.fn().mockResolvedValue(mockResponse);\n const z = { request: mockRequest };\n\n const result = await chatCompletion.operation.perform(z, bundle);\n\n expect(mockRequest).toHaveBeenCalledTimes(1);\n expect(mockRequest).toHaveBeenCalledWith({\n url: expect.stringContaining('/chat/completions'),\n method: 'POST',\n body: expect.stringMatching(/image_url.*example.com/),\n });\n\n expect(result).toEqual(mockResponse.data);\n });\n\n it('handles API errors', async () => {\n const bundle = {\n inputData: {\n user_message: 'Hello',\n model: DEFAULT_MODEL,\n },\n };\n\n const mockRequest = jest\n .fn()\n .mockRejectedValue(new Error('Invalid request'));\n const z = { request: mockRequest };\n\n try {\n await chatCompletion.operation.perform(z, bundle);\n } catch (error) {\n expect(mockRequest).toHaveBeenCalledTimes(1);\n expect(error.message).toContain('Invalid request');\n return;\n }\n throw new Error('Should have thrown an error');\n });\n});\n\n```\n\n## `test/list_models.test.js`\n\n```js\n/* globals describe, it, expect */\n/* eslint-disable no-undef */\n\nconst listModels = require('../dynamic_dropdowns/list_models');\n\ndescribe('list_models', () => {\n beforeEach(() => {\n jest.clearAllMocks();\n });\n\n it('returns formatted list of models', async () => {\n const mockResponse = {\n data: {\n data: [{ id: 'gpt-4' }, { id: 'gpt-3.5-turbo' }],\n },\n };\n\n const mockRequest = jest.fn().mockResolvedValue(mockResponse);\n const z = { request: mockRequest };\n const bundle = {};\n\n const results = await listModels.operation.perform(z, bundle);\n\n expect(mockRequest).toHaveBeenCalledTimes(1);\n expect(mockRequest).toHaveBeenCalledWith({\n url: expect.stringContaining('/models'),\n });\n\n expect(results).toEqual([\n { id: 'gpt-4', name: 'gpt-4' },\n { id: 'gpt-3.5-turbo', name: 'gpt-3.5-turbo' },\n ]);\n });\n\n it('handles API errors', async () => {\n const mockRequest = jest\n .fn()\n .mockRejectedValue(new Error('Failed to fetch models'));\n const z = { request: mockRequest };\n const bundle = {};\n\n try {\n await listModels.operation.perform(z, bundle);\n } catch (error) {\n expect(mockRequest).toHaveBeenCalledTimes(1);\n expect(error.message).toContain('Failed to fetch models');\n return;\n }\n throw new Error('Should have thrown an error');\n });\n});\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/openai", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/openai", "section": "templates", "tags": ["example", "template"], "related": [], "meta": {"files": ["constants.js", "index.js", "README.md", "package.json", "middleware.js", "authentication.js", "creates/index.js", "creates/chat_completion.js", "test/list_models.test.js", "test/authentication.test.js", "test/chat_completion.test.js", "dynamic_dropdowns/index.js", "dynamic_dropdowns/list_models.js", "samples/chat.json"], "auth": null, "pattern": "example", "local": "repos/zapier-platform/example-apps/openai"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:resource", "kind": "template", "key": "resource", "title": "Source template: resource", "summary": "Full example-app source (n/a / resource).", "body": "# example-app `resource`\n\nAuth: `n/a` · Pattern: `resource`\n\n## `README.md`\n\n```md\n# \"Resource\" Example App For Zapier Platform\n\n[![Build Status](https://travis-ci.org/zapier/zapier-platform-example-app-resource.svg?branch=master)](https://travis-ci.org/zapier/zapier-platform-example-app-resource)\n\nA barebones app that has a resource defined.\n\n> We recommend using the zapier-platform-cli and `zapier-platform init .`  to create an app - youll be presented with a list of currently available templates to start with.\n\n```\n\n## `index.js`\n\n```js\nconst Recipe = require('./resources/recipe');\n\nconst addAuthHeader = (request, z, bundle) => {\n // Hard-coded authentication just for demo\n request.headers['X-API-Key'] = 'secret';\n return request;\n};\n\n// Now we can roll up all our behaviors in an App.\nconst App = {\n // This is just shorthand to reference the installed dependencies you have. Zapier will\n // need to know these before we can upload\n version: require('./package.json').version,\n platformVersion: require('zapier-platform-core').version,\n\n beforeRequest: [addAuthHeader],\n\n afterResponse: [],\n\n // If you want your resource to show up, you better include it here!\n resources: {\n [Recipe.key]: Recipe,\n },\n\n // If you want your trigger to show up, you better include it here!\n triggers: {},\n\n // If you want your searches to show up, you better include it here!\n searches: {},\n\n // If you want your creates to show up, you better include it here!\n creates: {},\n};\n\n// Finally, export the app.\nmodule.exports = App;\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"zapier-platform-example-app-resource\",\n \"version\": \"1.0.0\",\n \"description\": \"An example app for the Zapier platform.\",\n \"repository\": \"zapier/zapier-platform-example-app-resource\",\n \"homepage\": \"https://zapier.com/\",\n \"author\": \"Bryan Helmig <bryan@zapier.com>\",\n \"license\": \"BSD-3-Clause\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"mocha --recursive\"\n },\n \"engines\": {\n \"node\": \">=8.10.0\",\n \"npm\": \">=5.6.0\"\n },\n \"dependencies\": {\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"mocha\": \"^5.2.0\",\n \"should\": \"^13.2.0\"\n },\n \"private\": true\n}\n\n```\n\n## `resources/recipe.js`\n\n```js\nconst _sharedBaseUrl = 'https://auth-json-server.zapier-staging.com';\n\nconst getRecipe = (z, bundle) => {\n return z\n .request({\n url: `${_sharedBaseUrl}/recipes/${bundle.inputData.id}`,\n })\n .then((response) => response.data);\n};\n\nconst listRecipes = (z, bundle) => {\n return z\n .request({\n url: _sharedBaseUrl + '/recipes',\n params: {\n style: bundle.inputData.style,\n },\n })\n .then((response) => response.data);\n};\n\nconst createRecipe = (z, bundle) => {\n const requestOptions = {\n url: _sharedBaseUrl + '/recipes',\n method: 'POST',\n body: {\n name: bundle.inputData.name,\n directions: bundle.inputData.directions,\n authorId: bundle.inputData.authorId,\n },\n headers: {\n 'content-type': 'application/json',\n },\n };\n\n return z.request(requestOptions).then((response) => response.data);\n};\n\nconst searchRecipe = (z, bundle) => {\n return z\n .request({\n url: _sharedBaseUrl + '/recipes',\n params: {\n nameSearch: bundle.inputData.name,\n },\n })\n .then((response) => {\n const matchingRecipes = response.data;\n\n // Only return the first matching recipe\n if (matchingRecipes && matchingRecipes.length) {\n return [matchingRecipes[0]];\n }\n\n return [];\n });\n};\n\nconst sample = {\n id: 1,\n createdAt: 1472069465,\n name: 'Best Spagetti Ever',\n authorId: 1,\n directions: '1. Boil Noodles\\n2.Serve with sauce',\n style: 'italian',\n};\n\n// This file exports a Recipe resource. The definition below contains all of the keys available,\n// and implements the list and create methods.\nmodule.exports = {\n key: 'recipe',\n noun: 'Recipe',\n // The get method is used by Zapier to fetch a complete representation of a record. This is helpful when the HTTP\n // response from a create call only return an ID, or a search that only returns a minimuml representation of the\n // record. Zapier will follow these up with the get() to retrieve the entire object.\n get: {\n display: {\n label: 'Get Recipe',\n description: 'Gets a recipe.',\n },\n operation: {\n inputFields: [{ key: 'id', required: true }],\n perform: getRecipe,\n sample: sample,\n },\n },\n // The list method on this resource becomes a Trigger on the app. Zapier will use polling to watch for new records\n list: {\n display: {\n label: 'New Recipe',\n description: 'Trigger when a new recipe is added.',\n },\n operation: {\n inputFields: [\n {\n key: 'style',\n type: 'string',\n helpText: 'Explain what style of cuisine this is.',\n },\n ],\n perform: listRecipes,\n sample: sample,\n },\n },\n // If your app supports webhooks, you can define a hook method instead of a list method.\n // Zapier will turn this into a webhook Trigger on the app.\n // hook: {\n //\n // },\n\n // The create method on this resource becomes a Write on this app\n create: {\n display: {\n label: 'Create Recipe',\n description: 'Creates a new recipe.',\n },\n operation: {\n inputFields: [\n { key: 'name', required: true, type: 'string' },\n {\n key: 'directions',\n required: true,\n type: 'text',\n helpText: 'Explain how should one make the recipe, step by step.',\n },\n {\n key: 'authorId',\n required: true,\n type: 'integer',\n label: 'Author ID',\n },\n {\n key: 'style',\n required: false,\n type: 'string',\n helpText: 'Explain what style of cuisine this is.',\n },\n ],\n perform: createRecipe,\n sample: sample,\n },\n },\n // The search method on this resource becomes a Search on this app\n search: {\n display: {\n label: 'Find Recipe',\n description: 'Finds an existing recipe by name.',\n },\n operation: {\n inputFields: [{ key: 'name', required: true, type: 'string' }],\n perform: searchRecipe,\n sample: sample,\n },\n },\n\n // In cases where Zapier needs to show an example record to the user, but we are unable to get a live example\n // from the API, Zapier will fallback to this hard-coded sample. It should reflect the data structure of\n // returned records, and have obviously dummy values that we can show to any user.\n sample: sample,\n\n // If the resource can have fields that are custom on a per-user basis, define a function to fetch the custom\n // field definitions. The result will be used to augment the sample.\n // outputFields: () => { return []; }\n // Alternatively, a static field definition should be provided, to specify labels for the fields\n outputFields: [\n { key: 'id', label: 'ID' },\n { key: 'createdAt', label: 'Created At' },\n { key: 'name', label: 'Name' },\n { key: 'directions', label: 'Directions' },\n { key: 'authorId', label: 'Author ID' },\n { key: 'style', label: 'Style' },\n ],\n};\n\n```\n\n## `test/resources/recipe.js`\n\n```js\n/* globals describe, it */\n\nrequire('should');\n\nconst zapier = require('zapier-platform-core');\n\nconst App = require('../../index');\nconst appTester = zapier.createAppTester(App);\n\ndescribe('recipe resource', () => {\n it('should get an existing recipe', (done) => {\n const bundle = {\n inputData: {\n id: 1,\n },\n };\n\n appTester(App.resources.recipe.get.operation.perform, bundle)\n .then((results) => {\n results.name.should.eql('name 1');\n results.directions.should.eql('directions 1');\n done();\n })\n .catch(done);\n });\n\n it('should list existing recipes', (done) => {\n const bundle = {\n inputData: {\n style: 'style 2',\n },\n };\n\n appTester(App.resources.recipe.list.operation.perform, bundle)\n .then((results) => {\n results.length.should.above(0);\n\n const firstRecipe = results[0];\n firstRecipe.name.should.eql('name 2');\n firstRecipe.directions.should.eql('directions 2');\n done();\n })\n .catch(done);\n });\n\n it('should create a new recipe', (done) => {\n const bundle = {\n inputData: {\n name: 'Smith Family Recipe',\n directions: '1. Order out :)',\n authorId: 1,\n },\n };\n\n appTester(App.resources.recipe.create.operation.perform, bundle)\n .then((results) => {\n results.should.have.property('name');\n done();\n })\n .catch(done);\n });\n\n it('should find a recipe', (done) => {\n const bundle = {\n inputData: {\n name: 'Smith Family Recipe',\n },\n };\n\n appTester(App.resources.recipe.search.operation.perform, bundle)\n .then((results) => {\n results[0].should.have.property('name');\n done();\n })\n .catch(done);\n });\n});\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/resource", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/resource", "section": "templates", "tags": ["example", "resource", "template"], "related": [], "meta": {"files": ["index.js", "README.md", "package.json", "resources/recipe.js", "test/resources/recipe.js"], "auth": null, "pattern": "resource", "local": "repos/zapier-platform/example-apps/resource"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:rest-hooks", "kind": "template", "key": "rest-hooks", "title": "Source template: rest-hooks", "summary": "Full example-app source (n/a / rest-hooks).", "body": "# example-app `rest-hooks`\n\nAuth: `n/a` · Pattern: `rest-hooks`\n\n## `README.md`\n\n```md\n# \"REST Hooks\" Trigger Example App For Zapier Platform\n\n[![Build Status](https://travis-ci.org/zapier/zapier-platform-example-app-rest-hooks.svg?branch=master)](https://travis-ci.org/zapier/zapier-platform-example-app-rest-hooks)\n\nA barebones app that has a [REST Hook](https://resthooks.org) trigger defined.\n\n> We recommend using the zapier-platform-cli and `zapier-platform init .`  to create an app - youll be presented with a list of currently available templates to start with.\n\n```\n\n## `index.js`\n\n```js\nconst recipe = require('./triggers/recipe');\n\n// Now we can roll up all our behaviors in an App.\nconst App = {\n // This is just shorthand to reference the installed dependencies you have. Zapier will\n // need to know these before we can upload\n version: require('./package.json').version,\n platformVersion: require('zapier-platform-core').version,\n\n beforeRequest: [],\n\n afterResponse: [],\n\n resources: {},\n\n // If you want your trigger to show up, you better include it here!\n triggers: {\n [recipe.key]: recipe,\n },\n\n // If you want your searches to show up, you better include it here!\n searches: {},\n\n // If you want your creates to show up, you better include it here!\n creates: {},\n};\n\n// Finally, export the app.\nmodule.exports = App;\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"zapier-platform-example-app-rest-hooks\",\n \"version\": \"1.0.0\",\n \"description\": \"An example app for the Zapier platform.\",\n \"repository\": \"zapier/zapier-platform-example-app-rest-hooks\",\n \"homepage\": \"https://zapier.com/\",\n \"author\": \"Bryan Helmig <bryan@zapier.com>\",\n \"license\": \"BSD-3-Clause\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"mocha --recursive\"\n },\n \"engines\": {\n \"node\": \">=8.10.0\",\n \"npm\": \">=5.6.0\"\n },\n \"dependencies\": {\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"mocha\": \"^5.2.0\",\n \"should\": \"^13.2.0\"\n },\n \"private\": true\n}\n\n```\n\n## `test/triggers.js`\n\n```js\n/* globals describe, it */\n\nrequire('should');\n\nconst zapier = require('zapier-platform-core');\n\nconst App = require('../index');\nconst appTester = zapier.createAppTester(App);\n\ndescribe('triggers', () => {\n describe('new recipe trigger', () => {\n it('should load recipe from fake hook', (done) => {\n const bundle = {\n inputData: {\n style: 'mediterranean',\n },\n cleanedRequest: {\n id: 1,\n name: 'name 1',\n directions: 'directions 1',\n },\n };\n\n appTester(App.triggers.recipe.operation.perform, bundle)\n .then((results) => {\n results.length.should.eql(1);\n\n const firstRecipe = results[0];\n firstRecipe.name.should.eql('name 1');\n firstRecipe.directions.should.eql('directions 1');\n\n done();\n })\n .catch(done);\n });\n\n it('should load recipe from list', (done) => {\n const bundle = {\n inputData: {\n style: 'mediterranean',\n },\n meta: {\n frontend: true,\n },\n };\n\n appTester(App.triggers.recipe.operation.performList, bundle)\n .then((results) => {\n results.length.should.be.greaterThan(1);\n\n const firstRecipe = results[0];\n firstRecipe.name.should.eql('name 1');\n firstRecipe.directions.should.eql('directions 1');\n\n done();\n })\n .catch(done);\n });\n });\n});\n\n```\n\n## `triggers/recipe.js`\n\n```js\nconst subscribeHook = (z, bundle) => {\n // `z.console.log()` is similar to `console.log()`.\n z.console.log('console says hello world!');\n\n // bundle.targetUrl has the Hook URL this app should call when a recipe is created.\n // https://platform.zapier.com/build/bundle#targeturl\n const data = {\n url: bundle.targetUrl,\n style: bundle.inputData.style,\n };\n\n // You can build requests and our client will helpfully inject all the variables\n // you need to complete. You can also register middleware to control this.\n const options = {\n url: 'https://57b20fb546b57d1100a3c405.mockapi.io/api/hooks',\n method: 'POST',\n body: data,\n };\n\n // You may return a promise or a normal data structure from any perform method.\n\n // If your webhook subscriptions expire, make sure the subscribe endpoint returns an `expiration_date` property containing an ISO8601 date.\n // The platform will automatically attempt to resubscribe after the expiration date. More details here: https://platform.zapier.com/build/cli-hook-trigger#prerequisites\n\n return z.request(options).then((response) => response.data);\n};\n\nconst unsubscribeHook = (z, bundle) => {\n // bundle.subscribeData contains the parsed response JSON from the subscribe request.\n const hookId = bundle.subscribeData.id;\n\n // You can build requests and our client will helpfully inject all the variables\n // you need to complete. You can also register middleware to control this.\n const options = {\n url: `https://57b20fb546b57d1100a3c405.mockapi.io/api/hooks/${hookId}`,\n method: 'DELETE',\n };\n\n // You may return a promise or a normal data structure from any perform method.\n return z.request(options).then((response) => response.data);\n};\n\nconst getRecipe = (z, bundle) => {\n // bundle.cleanedRequest will include the parsed JSON object (if it's not a\n // test poll) and also a .querystring property with the URL's query string.\n const recipe = {\n id: bundle.cleanedRequest.id,\n name: bundle.cleanedRequest.name,\n directions: bundle.cleanedRequest.directions,\n style: bundle.cleanedRequest.style,\n authorId: bundle.cleanedRequest.authorId,\n createdAt: bundle.cleanedRequest.createdAt,\n };\n\n return [recipe];\n};\n\nconst getFallbackRealRecipe = (z, bundle) => {\n // For the test poll, you should get some real data, to aid the setup process.\n const options = {\n url: 'https://57b20fb546b57d1100a3c405.mockapi.io/api/recipes/',\n params: {\n style: bundle.inputData.style,\n },\n };\n\n return z.request(options).then((response) => response.data);\n};\n\n// We recommend writing your triggers separate like this and rolling them\n// into the App definition at the end.\nmodule.exports = {\n key: 'recipe',\n\n // You'll want to provide some helpful display labels and descriptions\n // for users. Zapier will put them into the UI.\n noun: 'Recipe',\n display: {\n label: 'New Recipe',\n description: 'Trigger when a new recipe is added.',\n },\n\n // `operation` is where the business logic goes.\n operation: {\n // `inputFields` can define the fields a user could provide,\n // we'll pass them in as `bundle.inputData` later.\n inputFields: [\n {\n key: 'style',\n type: 'string',\n helpText: 'Which styles of cuisine this should trigger on.',\n },\n ],\n\n type: 'hook',\n\n performSubscribe: subscribeHook,\n performUnsubscribe: unsubscribeHook,\n\n perform: getRecipe,\n performList: getFallbackRealRecipe,\n\n // In cases where Zapier needs to show an example record to the user, but we are unable to get a live example\n // from the API, Zapier will fallback to this hard-coded sample. It should reflect the data structure of\n // returned records, and have obviously dummy values that we can show to any user.\n sample: {\n id: 1,\n createdAt: 1472069465,\n name: 'Best Spaghetti Ever',\n authorId: 1,\n directions: '1. Boil Noodles\\n2.Serve with sauce',\n style: 'italian',\n },\n\n // If the resource can have fields that are custom on a per-user basis, define a function to fetch the custom\n // field definitions. The result will be used to augment the sample.\n // outputFields: () => { return []; }\n // Alternatively, a static field definition should be provided, to specify labels for the fields\n outputFields: [\n { key: 'id', label: 'ID' },\n { key: 'createdAt', label: 'Created At' },\n { key: 'name', label: 'Name' },\n { key: 'directions', label: 'Directions' },\n { key: 'authorId', label: 'Author ID' },\n { key: 'style', label: 'Style' },\n ],\n },\n};\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/rest-hooks", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/rest-hooks", "section": "templates", "tags": ["example", "rest-hooks", "template"], "related": [], "meta": {"files": ["index.js", "README.md", "package.json", "test/triggers.js", "triggers/recipe.js"], "auth": null, "pattern": "rest-hooks", "local": "repos/zapier-platform/example-apps/rest-hooks"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:search", "kind": "template", "key": "search", "title": "Source template: search", "summary": "Full example-app source (n/a / search).", "body": "# example-app `search`\n\nAuth: `n/a` · Pattern: `search`\n\n## `README.md`\n\n```md\n# HTTP Search Example App For Zapier Platform\n\n[![Build Status](https://travis-ci.org/zapier/zapier-platform-example-app-search.svg?branch=master)](https://travis-ci.org/zapier/zapier-platform-example-app-search)\n\nA simple app that demonstrates how to write a simple search action.\n\n> We recommend using the zapier-platform-cli and `zapier-platform init .`  to create an app - youll be presented with a list of currently available templates to start with.\n\n```\n\n## `index.js`\n\n```js\nconst search = require('./searches/recipe');\n\nconst addAuthHeader = (request, z, bundle) => {\n // Hard-coded auth header just for demo\n request.headers['X-API-Key'] = 'secret';\n return request;\n};\n\n// Now we can roll up all our behaviors in an App.\nconst App = {\n // This is just shorthand to reference the installed dependencies you have. Zapier will\n // need to know these before we can upload\n version: require('./package.json').version,\n platformVersion: require('zapier-platform-core').version,\n\n beforeRequest: [addAuthHeader],\n\n afterResponse: [],\n\n resources: {},\n\n // If you want your trigger to show up, you better include it here!\n triggers: {},\n\n // If you want your searches to show up, you better include it here!\n searches: {\n [search.key]: search,\n },\n\n // If you want your creates to show up, you better include it here!\n creates: {},\n};\n\n// Finally, export the app.\nmodule.exports = App;\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"zapier-platform-example-app-search\",\n \"version\": \"1.0.0\",\n \"description\": \"An example app for the Zapier platform.\",\n \"repository\": \"zapier/zapier-platform-example-app-search\",\n \"homepage\": \"https://zapier.com/\",\n \"author\": \"Bryan Helmig <bryan@zapier.com>\",\n \"license\": \"BSD-3-Clause\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"mocha --recursive\"\n },\n \"engines\": {\n \"node\": \">=8.10.0\",\n \"npm\": \">=5.6.0\"\n },\n \"dependencies\": {\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"mocha\": \"^5.2.0\",\n \"should\": \"^13.2.0\"\n },\n \"private\": true\n}\n\n```\n\n## `searches/recipe.js`\n\n```js\nmodule.exports = {\n key: 'recipe',\n\n // You'll want to provide some helpful display labels and descriptions\n // for users. Zapier will put them into the UX.\n noun: 'Recipe',\n display: {\n label: 'Find a Recipe',\n description: 'Search for recipe by cuisine style.',\n },\n\n // `operation` is where we make the call to your API to do the search\n operation: {\n // This search only has one search field. Your searches might have just one, or many\n // search fields.\n inputFields: [\n {\n key: 'style',\n type: 'string',\n label: 'Style',\n helpText:\n 'Cuisine style to limit to the search to (i.e. mediterranean or italian).',\n },\n ],\n\n perform: (z, bundle) => {\n const url = 'https://auth-json-server.zapier-staging.com/recipes';\n\n // Put the search value in a query param. The details of how to build\n // a search URL will depend on how your API works.\n const options = {\n params: {\n style: bundle.inputData.style,\n },\n };\n\n return z.request(url, options).then((response) => response.data);\n },\n\n // In cases where Zapier needs to show an example record to the user, but we are unable to get a live example\n // from the API, Zapier will fallback to this hard-coded sample. It should reflect the data structure of\n // returned records, and have obviously dummy values that we can show to any user.\n sample: {\n id: 1,\n createdAt: 1472069465,\n name: 'Best Spagetti Ever',\n authorId: 1,\n directions: '1. Boil Noodles\\n2.Serve with sauce',\n style: 'italian',\n },\n\n // If the resource can have fields that are custom on a per-user basis, define a function to fetch the custom\n // field definitions. The result will be used to augment the sample.\n // outputFields: () => { return []; }\n // Alternatively, a static field definition should be provided, to specify labels for the fields\n outputFields: [\n { key: 'id', label: 'ID' },\n { key: 'createdAt', label: 'Created At' },\n { key: 'name', label: 'Name' },\n { key: 'directions', label: 'Directions' },\n { key: 'authorId', label: 'Author ID' },\n { key: 'style', label: 'Style' },\n ],\n },\n};\n\n```\n\n## `test/searches.js`\n\n```js\n/* globals describe, it */\n\nconst should = require('should'); // required to use .exist()\n\nconst zapier = require('zapier-platform-core');\n\nconst App = require('../index');\nconst appTester = zapier.createAppTester(App);\n\ndescribe('searches', () => {\n describe('search recipe', () => {\n it('should find a recipe', (done) => {\n const bundle = {\n inputData: {\n style: 'style 2',\n },\n };\n\n appTester(App.searches.recipe.operation.perform, bundle)\n .then((results) => {\n results.length.should.be.aboveOrEqual(1);\n\n const firstRecipe = results[0];\n firstRecipe.style.should.eql('style 2');\n should.exist(firstRecipe.name);\n should.exist(firstRecipe.directions);\n\n done();\n })\n .catch(done);\n });\n });\n});\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/search", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/search", "section": "templates", "tags": ["example", "search", "template"], "related": [], "meta": {"files": ["index.js", "README.md", "package.json", "searches/recipe.js", "test/searches.js"], "auth": null, "pattern": "search", "local": "repos/zapier-platform/example-apps/search"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:search-or-create", "kind": "template", "key": "search-or-create", "title": "Source template: search-or-create", "summary": "Full example-app source (n/a / create).", "body": "# example-app `search-or-create`\n\nAuth: `n/a` · Pattern: `create`\n\n## `README.md`\n\n```md\n# search-or-create\n\nThis Zapier integration project is generated by the `zapier-platform init` CLI command.\n\nThese are what you normally do next:\n\n```bash\n# Install dependencies\nnpm install # or you can use yarn\n\n# Run tests\nzapier-platform test\n\n# Register the integration on Zapier if you haven't\nzapier-platform register \"App Title\"\n\n# Or you can link to an existing integration on Zapier\nzapier-platform link\n\n# Push it to Zapier\nzapier-platform push\n```\n\nFind out more on the latest docs: https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md.\n\n# The \"search-or-create\" Template\n\nAn example showcasing a Search-or-Create.\n\n![](https://cdn.zappy.app/5fc31d104c6bd0050c44510557b3b98f.png)\n\n```\n\n## `creates/recipe.js`\n\n```js\nconst perform = async (z, bundle) => {\n const response = await z.request({\n method: 'POST',\n url: 'https://auth-json-server.zapier-staging.com/recipes',\n body: {\n name: bundle.inputData.name,\n },\n });\n return response.data;\n};\n\nmodule.exports = {\n key: 'recipe',\n noun: 'Recipe',\n\n display: {\n label: 'Create Recipe',\n description: 'Creates a recipe.',\n },\n\n operation: {\n inputFields: [\n { key: 'name', required: true },\n { key: 'directions', required: false },\n { key: 'style', required: false },\n ],\n perform,\n\n sample: {\n id: 1,\n name: 'Test',\n },\n },\n};\n\n```\n\n## `index.js`\n\n```js\nconst RecipeCreate = require('./creates/recipe');\nconst RecipeSearch = require('./searches/recipe');\n\nconst addAuthHeader = (request, z, bundle) => {\n // Hard-coded auth header just for demo. DON'T do auth like this for your\n // production app!\n request.headers['X-Api-Key'] = 'secret';\n return request;\n};\n\nmodule.exports = {\n version: require('./package.json').version,\n platformVersion: require('zapier-platform-core').version,\n\n beforeRequest: [addAuthHeader],\n\n searches: { [RecipeSearch.key]: RecipeSearch },\n\n creates: { [RecipeCreate.key]: RecipeCreate },\n\n searchOrCreates: {\n [RecipeSearch.key]: {\n // The key must match the search\n key: RecipeSearch.key, // same as above\n display: {\n // The label shows up when the search-or-create checkbox is checked.\n // See https://cdn.zappy.app/5fc31d104c6bd0050c44510557b3b98f.png\n label: 'Find or Create a Recipe',\n description: 'x', // this is ignored\n },\n search: RecipeSearch.key,\n create: RecipeCreate.key,\n },\n },\n};\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"search-or-create\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"jest --testTimeout 10000\"\n },\n \"dependencies\": {\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"jest\": \"^25.5.3\"\n },\n \"private\": true\n}\n\n```\n\n## `searches/recipe.js`\n\n```js\nconst perform = async (z, bundle) => {\n const response = await z.request({\n url: 'https://auth-json-server.zapier-staging.com/recipes',\n params: {\n name: bundle.inputData.name,\n },\n });\n return response.data;\n};\n\nmodule.exports = {\n key: 'recipe',\n noun: 'Recipe',\n\n display: {\n label: 'Find Recipe',\n description: 'Finds a recipe.',\n },\n\n operation: {\n inputFields: [\n {\n key: 'name',\n required: true,\n helpText: 'Find the Recipe with this name.',\n },\n ],\n perform,\n\n sample: {\n id: 1,\n name: 'Test',\n },\n },\n};\n\n```\n\n## `test/creates.test.js`\n\n```js\n/* globals describe, expect, test */\n\nconst zapier = require('zapier-platform-core');\n\nconst App = require('../index');\nconst appTester = zapier.createAppTester(App);\nzapier.tools.env.inject();\n\ndescribe('recipe', () => {\n test('create with a name', async () => {\n const bundle = { inputData: { name: 'Pancake' } };\n const result = await appTester(\n App.creates.recipe.operation.perform,\n bundle,\n );\n expect(result.id).toBeTruthy();\n expect(result.name).toBe('Pancake');\n });\n});\n\n```\n\n## `test/searches.test.js`\n\n```js\n/* globals describe, expect, test */\n\nconst zapier = require('zapier-platform-core');\n\nconst App = require('../index');\nconst appTester = zapier.createAppTester(App);\nzapier.tools.env.inject();\n\ndescribe('recipe', () => {\n test('search by name', async () => {\n const bundle = { inputData: { name: 'name 1' } };\n const results = await appTester(\n App.searches.recipe.operation.perform,\n bundle,\n );\n expect(results.length).toBeGreaterThan(0);\n\n const firstRecipe = results[0];\n expect(firstRecipe).toMatchObject({\n id: '1',\n name: 'name 1',\n });\n });\n});\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/search-or-create", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/search-or-create", "section": "templates", "tags": ["create", "example", "template"], "related": [], "meta": {"files": ["index.js", "README.md", "package.json", "creates/recipe.js", "searches/recipe.js", "test/searches.test.js", "test/creates.test.js"], "auth": null, "pattern": "create", "local": "repos/zapier-platform/example-apps/search-or-create"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:session-auth", "kind": "template", "key": "session-auth", "title": "Source template: session-auth", "summary": "Full example-app source (session-auth / example).", "body": "# example-app `session-auth`\n\nAuth: `session-auth` · Pattern: `example`\n\n## `README.md`\n\n```md\n# session-auth\n\nThis Zapier integration project is generated by the `zapier-platform init` CLI command.\n\nThese are what you normally do next:\n\n```bash\n# Install dependencies\nnpm install # or you can use yarn\n\n# Run tests\nzapier-platform test\n\n# Register the integration on Zapier if you haven't\nzapier-platform register \"App Title\"\n\n# Or you can link to an existing integration on Zapier\nzapier-platform link\n\n# Push it to Zapier\nzapier-platform push\n```\n\nThen, to add more features, you can use the `zapier-platform scaffold` command, for example:\n\n```bash\n# Add a trigger\nzapier-platform scaffold trigger contact\n\n# Add an action\nzapier-platform scaffold create contact\n``` \n\nFind out more on the latest docs: https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md.\n\n```\n\n## `authentication.js`\n\n```js\n'use strict';\n\n// You want to make a request to an endpoint that is either specifically designed\n// to test auth, or one that every user will have access to. eg: `/me`.\n// By returning the entire request object, you have access to the request and\n// response data for testing purposes. Your connection label can access any data\n// from the returned response using the `json.` prefix. eg: `{{json.username}}`.\nconst test = (z, bundle) =>\n z.request({ url: 'https://auth-json-server.zapier-staging.com/me' });\n\nconst getSessionKey = async (z, bundle) => {\n const response = await z.request({\n url: 'https://httpbin.zapier-tooling.com/post',\n method: 'POST',\n body: {\n username: bundle.authData.username,\n password: bundle.authData.password,\n },\n });\n\n // If you're using core v9.x or older, you should call response.throwForStatus()\n // or verify response.status === 200 before you continue.\n return {\n // FIXME: The `|| \"secret\"` below is just for demo purposes, you should remove it.\n sessionKey: response.data.sessionKey || 'secret',\n };\n};\n\nmodule.exports = {\n // \"session\" auth exchanges user data for a different session token (that may be\n // periodically refreshed\")\n type: 'session',\n sessionConfig: { perform: getSessionKey },\n\n // Define any input app's auth requires here. The user will be prompted to enter\n // this info when they connect their account.\n fields: [\n { key: 'username', label: 'Username', required: true },\n {\n key: 'password',\n label: 'Password',\n required: true,\n\n // this lets the user enter masked data\n type: 'password',\n },\n ],\n\n // The test method allows Zapier to verify that the credentials a user provides\n // are valid. We'll execute this method whenever a user connects their account for\n // the first time.\n test,\n\n // This template string can access all the data returned from the auth test. If\n // you return the test object, you'll access the returned data with a label like\n // `{{json.X}}`. If you return `response.data` from your test, then your label can\n // be `{{X}}`. This can also be a function that returns a label. That function has\n // the standard args `(z, bundle)` and data returned from the test can be accessed\n // in `bundle.inputData.X`.\n connectionLabel: '{{json.username}}',\n};\n\n```\n\n## `index.js`\n\n```js\nconst authentication = require('./authentication');\nconst { befores = [], afters = [] } = require('./middleware');\n\nmodule.exports = {\n // This is just shorthand to reference the installed dependencies you have.\n // Zapier will need to know these before we can upload.\n version: require('./package.json').version,\n platformVersion: require('zapier-platform-core').version,\n\n authentication,\n\n beforeRequest: [...befores],\n\n afterResponse: [...afters],\n\n // If you want your trigger to show up, you better include it here!\n triggers: {},\n\n // If you want your searches to show up, you better include it here!\n searches: {},\n\n // If you want your creates to show up, you better include it here!\n creates: {},\n\n resources: {},\n};\n\n```\n\n## `middleware.js`\n\n```js\n'use strict';\n\n// This function runs before every outbound request. You can have as many as you\n// need. They'll need to each be registered in your index.js file.\nconst includeSessionKeyHeader = (request, z, bundle) => {\n if (bundle.authData.sessionKey) {\n request.headers = request.headers || {};\n request.headers['X-API-Key'] = bundle.authData.sessionKey;\n }\n\n return request;\n};\n\nmodule.exports = { befores: [includeSessionKeyHeader], afters: [] };\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"session-auth\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"jest --testTimeout 10000\"\n },\n \"dependencies\": {\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"jest\": \"^29.6.0\"\n },\n \"private\": true\n}\n\n```\n\n## `test/authentication.test.js`\n\n```js\n/* globals describe, it, expect */\n\nconst zapier = require('zapier-platform-core');\n\nconst App = require('../index');\nconst appTester = zapier.createAppTester(App);\n\ndescribe('session auth app', () => {\n it('has an exchange for username/password', async () => {\n const bundle = {\n authData: {\n username: 'bryan',\n password: 'hunter2',\n },\n };\n\n const newAuthData = await appTester(\n App.authentication.sessionConfig.perform,\n bundle,\n );\n\n expect(newAuthData.sessionKey).toBe('secret');\n });\n\n it('has auth details added to every request', async () => {\n const bundle = {\n authData: {\n sessionKey: 'secret',\n },\n };\n\n const response = await appTester(App.authentication.test, bundle);\n\n expect(response.status).toBe(200);\n expect(response.request.headers['X-API-Key']).toBe('secret');\n });\n});\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/session-auth", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/session-auth", "section": "templates", "tags": ["example", "session-auth", "template"], "related": ["zapier-platform init --template session-auth"], "meta": {"files": ["index.js", "README.md", "package.json", "middleware.js", "authentication.js", "test/authentication.test.js"], "auth": "session-auth", "pattern": "example", "local": "repos/zapier-platform/example-apps/session-auth"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:session-auth-typescript", "kind": "template", "key": "session-auth-typescript", "title": "Source template: session-auth-typescript", "summary": "Full example-app source (session-auth / example).", "body": "# example-app `session-auth-typescript`\n\nAuth: `session-auth` · Pattern: `example`\n\n## `README.md`\n\n```md\n# session-auth-typescript\n\nThis Zapier integration project is generated by the `zapier-platform init` CLI command.\n\nThese are what you normally do next:\n\n```bash\n# Install dependencies\nnpm install # or you can use yarn\n\n# Run tests\nzapier-platform test\n\n# Register the integration on Zapier if you haven't\nzapier-platform register \"App Title\"\n\n# Or you can link to an existing integration on Zapier\nzapier-platform link\n\n# Push it to Zapier\nzapier-platform push\n```\n\nThen, to add more features, you can use the `zapier-platform scaffold` command, for example:\n\n```bash\n# Add a trigger\nzapier-platform scaffold trigger contact\n\n# Add an action\nzapier-platform scaffold create contact\n``` \n\nFind out more on the latest docs: https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md.\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"session-auth-typescript\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"scripts\": {\n \"test\": \"npm run build && vitest --run\",\n \"clean\": \"rimraf ./dist ./build\",\n \"build\": \"npm run clean && tsc\",\n \"_zapier-build\": \"npm run build\"\n },\n \"dependencies\": {\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"rimraf\": \"^5.0.10\",\n \"typescript\": \"5.6.2\",\n \"vitest\": \"^2.1.2\"\n },\n \"private\": true,\n \"exports\": \"./dist/index.js\",\n \"type\": \"module\"\n}\n\n```\n\n## `src/authentication.ts`\n\n```ts\nimport type { ZObject, Bundle, Authentication } from 'zapier-platform-core';\n\n// You want to make a request to an endpoint that is either specifically designed\n// to test auth, or one that every user will have access to. eg: `/me`.\n// By returning the entire request object, you have access to the request and\n// response data for testing purposes. Your connection label can access any data\n// from the returned response using the `json.` prefix. eg: `{{json.username}}`.\nconst test = (z: ZObject, bundle: Bundle) =>\n z.request({ url: 'https://auth-json-server.zapier-staging.com/me' });\n\nconst getSessionKey = async (z: ZObject, bundle: Bundle) => {\n const response = await z.request({\n url: 'https://httpbin.zapier-tooling.com/post',\n method: 'POST',\n body: {\n username: bundle.authData.username,\n password: bundle.authData.password,\n },\n });\n\n // If you're using core v9.x or older, you should call response.throwForStatus()\n // or verify response.status === 200 before you continue.\n return {\n // FIXME: The `|| \"secret\"` below is just for demo purposes, you should remove it.\n sessionKey: response.data.sessionKey || 'secret',\n };\n};\n\n// This function runs before every outbound request. You can have as many as you\n// need. They'll need to each be registered in your index.js file.\nconst includeSessionKeyHeader = (request, z: ZObject, bundle: Bundle) => {\n if (bundle.authData.sessionKey) {\n request.headers = request.headers || {};\n request.headers['X-API-Key'] = bundle.authData.sessionKey;\n }\n\n return request;\n};\n\nexport default {\n config: {\n // \"session\" auth exchanges user data for a different session token (that may be\n // periodically refreshed\")\n type: 'session',\n sessionConfig: { perform: getSessionKey },\n\n // Define any input app's auth requires here. The user will be prompted to enter\n // this info when they connect their account.\n fields: [\n { key: 'username', label: 'Username', required: true },\n {\n key: 'password',\n label: 'Password',\n required: true,\n\n // this lets the user enter masked data\n type: 'password',\n },\n ],\n\n // The test method allows Zapier to verify that the credentials a user provides\n // are valid. We'll execute this method whenever a user connects their account for\n // the first time.\n test,\n\n // This template string can access all the data returned from the auth test. If\n // you return the test object, you'll access the returned data with a label like\n // `{{json.X}}`. If you return `response.data` from your test, then your label can\n // be `{{X}}`. This can also be a function that returns a label. That function has\n // the standard args `(z: ZObject, bundle: Bundle)` and data returned from the\n // test can be accessed in `bundle.inputData.X`.\n connectionLabel: '{{json.username}}',\n } satisfies Authentication,\n befores: [includeSessionKeyHeader],\n afters: [],\n};\n\n```\n\n## `src/index.ts`\n\n```ts\nimport zapier, { defineApp } from 'zapier-platform-core';\n\nimport packageJson from '../package.json' with { type: 'json' };\n\nimport authenticationModule from './authentication.js';\nconst { config: authentication, befores, afters } = authenticationModule;\n\nexport default defineApp({\n version: packageJson.version,\n platformVersion: zapier.version,\n\n authentication,\n beforeRequest: [...befores],\n afterResponse: [...afters],\n\n // Add your triggers here for them to show up!\n triggers: {},\n\n // Add your creates here for them to show up!\n creates: {},\n});\n\n```\n\n## `src/test/authentication.test.ts`\n\n```ts\nimport { describe, expect, it } from 'vitest';\nimport zapier from 'zapier-platform-core';\n\nimport App from '../index.js';\nconst appTester = zapier.createAppTester(App);\n\ndescribe('session auth app', () => {\n it('has an exchange for username/password', async () => {\n const bundle = {\n authData: {\n username: 'bryan',\n password: 'hunter2',\n },\n };\n\n const newAuthData = await appTester(\n App.authentication.sessionConfig.perform,\n bundle,\n );\n\n expect(newAuthData.sessionKey).toBe('secret');\n });\n\n it('has auth details added to every request', async () => {\n const bundle = {\n authData: {\n sessionKey: 'secret',\n },\n };\n\n const response = await appTester(App.authentication.test, bundle);\n\n expect(response.status).toBe(200);\n expect(response.request.headers['X-API-Key']).toBe('secret');\n });\n});\n\n```\n\n## `tsconfig.json`\n\n```json\n{\n \"compilerOptions\": {\n \"target\": \"ESNext\",\n \"module\": \"NodeNext\",\n \"moduleResolution\": \"NodeNext\",\n \"resolveJsonModule\": true,\n \"esModuleInterop\": true,\n \"noUncheckedIndexedAccess\": true,\n \"isolatedModules\": true,\n \"noImplicitAny\": false,\n \"skipLibCheck\": true,\n \"outDir\": \"./dist\",\n \"rootDir\": \"./src\",\n \"strict\": true\n },\n \"include\": [\"./src/**/*.ts\"],\n \"exclude\": [\"./**/*.test.ts\"]\n}\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/session-auth-typescript", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/session-auth-typescript", "section": "templates", "tags": ["example", "session-auth", "template"], "related": ["zapier-platform init --template session-auth-typescript"], "meta": {"files": ["README.md", "package.json", "tsconfig.json", "src/authentication.ts", "src/index.ts", "src/test/authentication.test.ts"], "auth": "session-auth", "pattern": "example", "local": "repos/zapier-platform/example-apps/session-auth-typescript"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:trigger", "kind": "template", "key": "trigger", "title": "Source template: trigger", "summary": "Full example-app source (n/a / trigger).", "body": "# example-app `trigger`\n\nAuth: `n/a` · Pattern: `trigger`\n\n## `README.md`\n\n```md\n# \"Trigger\" Example App For Zapier Platform\n\n[![Build Status](https://travis-ci.org/zapier/zapier-platform-example-app-trigger.svg?branch=master)](https://travis-ci.org/zapier/zapier-platform-example-app-trigger)\n\nA barebones app that has a trigger defined.\n```\n\n## `index.js`\n\n```js\nconst recipe = require('./triggers/recipe');\n\nconst addAuthHeader = (request, z, bundle) => {\n // Hard-coded auth header just for demo\n request.headers['X-API-Key'] = 'secret';\n return request;\n};\n\n// Now we can roll up all our behaviors in an App.\nconst App = {\n // This is just shorthand to reference the installed dependencies you have. Zapier will\n // need to know these before we can upload\n version: require('./package.json').version,\n platformVersion: require('zapier-platform-core').version,\n\n beforeRequest: [addAuthHeader],\n\n afterResponse: [],\n\n resources: {},\n\n // If you want your trigger to show up, you better include it here!\n triggers: {\n [recipe.key]: recipe,\n },\n\n // If you want your searches to show up, you better include it here!\n searches: {},\n\n // If you want your creates to show up, you better include it here!\n creates: {},\n};\n\n// Finally, export the app.\nmodule.exports = App;\n\n```\n\n## `package.json`\n\n```json\n{\n \"name\": \"zapier-platform-example-app-trigger\",\n \"version\": \"1.0.0\",\n \"description\": \"An example app for the Zapier platform.\",\n \"repository\": \"zapier/zapier-platform-example-app-trigger\",\n \"homepage\": \"https://zapier.com/\",\n \"author\": \"Bryan Helmig <bryan@zapier.com>\",\n \"license\": \"BSD-3-Clause\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"mocha --recursive\"\n },\n \"engines\": {\n \"node\": \">=8.10.0\",\n \"npm\": \">=5.6.0\"\n },\n \"dependencies\": {\n \"zapier-platform-core\": \"19.1.0\"\n },\n \"devDependencies\": {\n \"mocha\": \"^5.2.0\",\n \"should\": \"^13.2.0\"\n },\n \"private\": true\n}\n\n```\n\n## `test/triggers.js`\n\n```js\n/* globals describe, it */\n\nrequire('should');\n\nconst zapier = require('zapier-platform-core');\nconst App = require('../index');\n\nconst appTester = zapier.createAppTester(App);\n\ndescribe('triggers', () => {\n describe('new recipe trigger', () => {\n it('should load recipes', async () => {\n const bundle = {\n inputData: {\n style: 'style 2',\n },\n };\n\n const results = await appTester(\n App.triggers.recipe.operation.perform,\n bundle,\n );\n\n results.length.should.above(0);\n\n const firstRecipe = results[0];\n firstRecipe.name.should.eql('name 2');\n firstRecipe.directions.should.eql('directions 2');\n });\n\n it('should load recipes without filters', async () => {\n const bundle = {};\n\n const results = await appTester(\n App.triggers.recipe.operation.perform,\n bundle,\n );\n\n results.length.should.above(1);\n\n const firstRecipe = results[0];\n firstRecipe.name.should.eql('name 1');\n firstRecipe.directions.should.eql('directions 1');\n });\n });\n});\n\n```\n\n## `triggers/recipe.js`\n\n```js\nconst listRecipes = async (z, bundle) => {\n // `z.console.log()` is similar to `console.log()`.\n z.console.log('console says hello world!');\n\n const params = {};\n if (bundle.inputData.style) {\n params.style = bundle.inputData.style;\n }\n\n // You can build requests and our client will helpfully inject all the variables\n // you need to complete. You can also register middleware to control this.\n const requestOptions = {\n url: 'https://auth-json-server.zapier-staging.com/recipes',\n params: params,\n };\n\n // z.request() returns an HTTP Response Object https://github.com/zapier/zapier-platform/tree/main/packages/cli#http-response-object\n const response = await z.request(requestOptions);\n\n return response.data;\n};\n\n// We recommend writing your triggers separate like this and rolling them\n// into the App definition at the end.\nmodule.exports = {\n key: 'recipe',\n\n // You'll want to provide some helpful display labels and descriptions\n // for users. Zapier will put them into the UX.\n noun: 'Recipe',\n display: {\n label: 'New Recipe',\n description: 'Triggers when a new recipe is added.',\n },\n\n // `operation` is where the business logic goes.\n operation: {\n // `inputFields` can define the fields a user could provide,\n // we'll pass them in as `bundle.inputData` later.\n inputFields: [\n {\n key: 'style',\n type: 'string',\n helpText: 'Which styles of cuisine this should trigger on.',\n },\n ],\n\n perform: listRecipes,\n\n // In cases where Zapier needs to show an example record to the user, but we are unable to get a live example\n // from the API, Zapier will fallback to this hard-coded sample. It should reflect the data structure of\n // returned records, and have obviously dummy values that we can show to any user.\n sample: {\n id: 1,\n createdAt: 1472069465,\n name: 'Best Spagetti Ever',\n authorId: 1,\n directions: '1. Boil Noodles\\n2.Serve with sauce',\n style: 'italian',\n },\n\n // If the resource can have fields that are custom on a per-user basis, define a function to fetch the custom\n // field definitions. The result will be used to augment the sample.\n // outputFields: [\n // () => { return []; }\n // ]\n // For a more complete example of using dynamic fields see\n // https://github.com/zapier/zapier-platform/tree/main/packages/cli#customdynamic-fields.\n // Alternatively, a static field definition should be provided, to specify labels for the fields\n outputFields: [\n { key: 'id', label: 'ID' },\n { key: 'createdAt', label: 'Created At' },\n { key: 'name', label: 'Name' },\n { key: 'directions', label: 'Directions' },\n { key: 'authorId', label: 'Author ID' },\n { key: 'style', label: 'Style' },\n ],\n },\n};\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "https://github.com/zapier/zapier-platform/tree/main/example-apps/trigger", "source_repo": "zapier/zapier-platform", "source_path": "zapier-platform/example-apps/trigger", "section": "templates", "tags": ["example", "template", "trigger"], "related": [], "meta": {"files": ["index.js", "README.md", "package.json", "test/triggers.js", "triggers/recipe.js"], "auth": null, "pattern": "trigger", "local": "repos/zapier-platform/example-apps/trigger"}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}
{"_id": "template:scratch-oauth2-typescript", "kind": "template", "key": "scratch-oauth2-typescript", "title": "Golden local project: scratch/oauth2-typescript", "summary": "CLI 19.1.0 `zapier-platform init --template oauth2 --language typescript`. Structurally valid after build.", "body": "## `src/authentication.ts`\n\n```ts\nimport type { ZObject, Bundle, Authentication } from 'zapier-platform-core';\n\nconst getAccessToken = async (z: ZObject, bundle: Bundle) => {\n const response = await z.request({\n url: 'https://auth-json-server.zapier-staging.com/oauth/access-token',\n method: 'POST',\n body: {\n client_id: process.env.CLIENT_ID,\n client_secret: process.env.CLIENT_SECRET,\n grant_type: 'authorization_code',\n code: bundle.inputData.code,\n\n // Extra data can be pulled from the querystring. For instance:\n // 'accountDomain': bundle.cleanedRequest.querystring.accountDomain\n },\n headers: { 'content-type': 'application/x-www-form-urlencoded' },\n });\n\n // If you're using core v9.x or older, you should call response.throwForStatus()\n // or verify response.status === 200 before you continue.\n\n // This function should return `access_token`.\n // If your app does an app refresh, then `refresh_token` should be returned here\n // as well\n return {\n access_token: response.data.access_token,\n refresh_token: response.data.refresh_token,\n };\n};\n\nconst refreshAccessToken = async (z: ZObject, bundle: Bundle) => {\n const response = await z.request({\n url: 'https://auth-json-server.zapier-staging.com/oauth/refresh-token',\n method: 'POST',\n body: {\n client_id: process.env.CLIENT_ID,\n client_secret: process.env.CLIENT_SECRET,\n grant_type: 'refresh_token',\n refresh_token: bundle.authData.refresh_token,\n },\n headers: { 'content-type': 'application/x-www-form-urlencoded' },\n });\n\n // If you're using core v9.x or older, you should call response.throwForStatus()\n // or verify response.status === 200 before you continue.\n\n // This function should return `access_token`.\n // If the refresh token stays constant, no need to return it.\n // If the refresh token does change, return it here to update the stored value in\n // Zapier\n return {\n access_token: response.data.access_token,\n refresh_token: response.data.refresh_token,\n };\n};\n\n// You want to make a request to an endpoint that is either specifically designed\n// to test auth, or one that every user will have access to. eg: `/me`.\n// By returning the entire request object, you have access to the request and\n// response data for testing purposes. Your connection label can access any data\n// from the returned response using the `json.` prefix. eg: `{{json.username}}`.\nconst test = (z: ZObject, bundle: Bundle) =>\n z.request({ url: 'https://auth-json-server.zapier-staging.com/me' });\n\nexport default {\n // OAuth2 is a web authentication standard. There are a lot of configuration\n // options that will fit most any situation.\n type: 'oauth2',\n oauth2Config: {\n authorizeUrl: {\n url: 'https://auth-json-server.zapier-staging.com/oauth/authorize',\n params: {\n client_id: '{{process.env.CLIENT_ID}}',\n state: '{{bundle.inputData.state}}',\n redirect_uri: '{{bundle.inputData.redirect_uri}}',\n response_type: 'code',\n },\n },\n getAccessToken,\n refreshAccessToken,\n autoRefresh: true,\n },\n\n // Define any input app's auth requires here. The user will be prompted to enter\n // this info when they connect their account.\n fields: [],\n\n // The test method allows Zapier to verify that the credentials a user provides\n // are valid. We'll execute this method whenever a user connects their account for\n // the first time.\n test,\n\n // This template string can access all the data returned from the auth test. If\n // you return the test object, you'll access the returned data with a label like\n // `{{json.X}}`. If you return `response.data` from your test, then your label can\n // be `{{X}}`. This can also be a function that returns a label. That function has\n // the standard args `(z: ZObject, bundle: Bundle)` and data returned from the\n // test can be accessed in `bundle.inputData.X`.\n connectionLabel: '{{json.username}}',\n} satisfies Authentication;\n\n```\n\n## `src/index.ts`\n\n```ts\nimport zapier, { defineApp } from 'zapier-platform-core';\n\nimport packageJson from '../package.json' with { type: 'json' };\n\nimport authentication from './authentication.js';\nimport { befores, afters } from './middleware.js';\n\nexport default defineApp({\n version: packageJson.version,\n platformVersion: zapier.version,\n\n authentication,\n beforeRequest: [...befores],\n afterResponse: [...afters],\n\n // Add your triggers here for them to show up!\n triggers: {},\n\n // Add your creates here for them to show up!\n creates: {},\n});\n\n```\n\n## `src/middleware.ts`\n\n```ts\nimport type { ZObject, Bundle, Authentication } from 'zapier-platform-core';\n\n// This function runs before every outbound request. You can have as many as you\n// need. They'll need to each be registered in your index.js file.\nconst includeBearerToken = (request, z: ZObject, bundle: Bundle) => {\n if (bundle.authData.access_token) {\n request.headers.Authorization = `Bearer ${bundle.authData.access_token}`;\n }\n\n return request;\n};\n\nexport const befores = [includeBearerToken];\n\nexport const afters = [];\n\n```\n\n## `src/test/authentication.test.ts`\n\n```ts\nimport { describe, expect, it, beforeAll } from 'vitest';\nimport zapier from 'zapier-platform-core';\n\nimport App from '../index.js';\nconst appTester = zapier.createAppTester(App);\n\n// Only defining the env vars here so the tests out of the box.\n// You should create a `.env` file and populate it with the necessarily configuration\n// it should look like:\n/*\n CLIENT_ID=1234\n CLIENT_SECRET=asdf\n*/\n// then you can delete the following 2 lines\nprocess.env.CLIENT_ID = process.env.CLIENT_ID || '1234';\nprocess.env.CLIENT_SECRET = process.env.CLIENT_SECRET || 'asdf';\n\ndescribe('authentication', () => {\n beforeAll(() => {\n // It's a good idea to store your Client ID and Secret in the environment rather than in code.\n if (!(process.env.CLIENT_ID && process.env.CLIENT_SECRET)) {\n throw new Error(\n `Before running the tests, make sure CLIENT_ID and CLIENT_SECRET are available in the environment.`,\n );\n }\n });\n\n it('generates an authorize URL', async () => {\n const bundle = {\n // In production, these will be generated by Zapier and set automatically\n inputData: {\n state: '4444',\n redirect_uri: 'https://zapier.com/',\n },\n environment: {\n CLIENT_ID: process.env.CLIENT_ID,\n CLIENT_SECRET: process.env.CLIENT_SECRET,\n },\n };\n\n const authorizeUrl = await appTester(\n App.authentication.oauth2Config.authorizeUrl,\n bundle,\n );\n\n expect(authorizeUrl).toBe(\n 'https://auth-json-server.zapier-staging.com/oauth/authorize?client_id=1234&state=4444&redirect_uri=https%3A%2F%2Fzapier.com%2F&response_type=code',\n );\n });\n\n it('can fetch an access token', async () => {\n const bundle = {\n inputData: {\n // In production, Zapier passes along whatever code your API set in the query params when it redirects\n // the user's browser to the `redirect_uri`\n code: 'one_time_code',\n },\n environment: {\n CLIENT_ID: process.env.CLIENT_ID,\n CLIENT_SECRET: process.env.CLIENT_SECRET,\n },\n cleanedRequest: {\n querystring: {\n accountDomain: 'test-account',\n code: 'one_time_code',\n },\n },\n rawRequest: {\n querystring: '?accountDomain=test-account&code=one_time_code',\n },\n };\n\n const result = await appTester(\n App.authentication.oauth2Config.getAccessToken,\n bundle,\n );\n\n expect(result.access_token).toBe('a_token');\n expect(result.refresh_token).toBe('a_refresh_token');\n });\n\n it('can refresh the access token', async () => {\n const bundle = {\n // In production, Zapier provides these. For testing, we have hard-coded them.\n // When writing tests for your own app, you should consider exporting them and doing process.env.MY_ACCESS_TOKEN\n authData: {\n access_token: 'a_token',\n refresh_token: 'a_refresh_token',\n },\n environment: {\n CLIENT_ID: process.env.CLIENT_ID,\n CLIENT_SECRET: process.env.CLIENT_SECRET,\n },\n };\n\n const result = await appTester(\n App.authentication.oauth2Config.refreshAccessToken,\n bundle,\n );\n expect(result.access_token).toBe('a_token');\n });\n\n it('includes the access token in future requests', async () => {\n const bundle = {\n authData: {\n access_token: 'a_token',\n refresh_token: 'a_refresh_token',\n },\n };\n\n const response = await appTester(App.authentication.test, bundle);\n expect(response.data).toHaveProperty('username');\n expect(response.data.username).toBe('Bret');\n });\n});\n\n```\n", "usage": "", "signature": "", "aliases": [], "flags": [], "args": [], "examples": [], "source_url": "", "source_repo": "", "source_path": "scratch/oauth2-typescript", "section": "templates", "tags": ["golden", "oauth2", "template", "typescript"], "related": ["init", "validate", "z.request"], "meta": {"cli_version": "19.1.0", "validated": true}, "ingested_at": "2026-08-18T00:54:23.096651+00:00"}