# Actions Use `features.marketplace_actions` to declare custom actions in your app manifest. An action is an operation your app can perform from a supported Zoom surface, such as an AI Agent tool. > **Does not include built-in actions** > This page covers custom actions that developers define in the manifest. Built-in actions are not documented on this page. Do not include `built_in_config` unless Zoom provides a documented built-in action for manifest use. For more information, see the **[Actions](/docs/build-flow/actions/)** page of the app build flow. ## Manifest JSON ```json { "features": { "marketplace_actions": { "enable": true, "actions": [ { "name": "Create CRM Record", "command_id": "create_crm_record", "description": "Create a CRM record from an AI Agent conversation.", "locations": ["VIRTUAL_AGENT"], "trigger_selection_type": "TRIGGER_ENDPOINT", "definition_type": 2, "standard_input_definition": { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "title": "Create CRM Record Input", "properties": { "title": { "type": "string", "title": "Title", "description": "Short title for the CRM record." }, "summary": { "type": "string", "title": "Summary", "description": "Conversation summary or context to include in the record." }, "priority": { "type": "string", "title": "Priority", "description": "Priority assigned to the record.", "enum": ["low", "medium", "high"], "default": "medium" } }, "required": ["title"] }, "standard_output_definition": { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "title": "Create CRM Record Output", "properties": { "recordId": { "type": "string", "title": "Record ID", "description": "Unique identifier of the record created by the app." }, "recordUrl": { "type": "string", "title": "Record URL", "description": "Direct URL where the user can open the created record." } }, "required": ["recordId"] }, "endpoint_key": "create_crm_record", "input_mapping": [ { "param_key": "title", "required": true, "mapping_template": "{{input.title}}" }, { "param_key": "summary", "required": false, "mapping_template": "{{input.summary}}" }, { "param_key": "priority", "required": false, "mapping_template": "{{input.priority}}" } ], "output_mapping": [ { "param_key": "recordId", "mapping_template": "{{response.id}}" }, { "param_key": "recordUrl", "mapping_template": "{{response.url}}" } ] } ] } } } ``` > **endpoint_key** > > The `endpoint_key` must match a Connect endpoint configured for your app. > > Use `input_mapping` to map action inputs to the endpoint request. > > Use `output_mapping` to map the endpoint response back to the action output. --- ## Available custom action location Use only action locations documented by Zoom as available for manifest custom actions. | Surface | Location | Action type | Notes | | :------------ | :-------------- | :--------------- | :----------------------------------------------------------------------------------- | | AI Agent tool | `VIRTUAL_AGENT` | Connect endpoint | Output field descriptions are required so the AI Agent can understand returned data. | > **Per-property descriptions** > > Locations that require descriptions (for example `AI_TOOL`) rely on the per-property `description` fields inside your `standard_output_definition` so AI tools can interpret the result. --- ## Connect endpoint example Use this mode when your action should call one of your app's Connect endpoints. ```json { "name": "Create CRM Record", "command_id": "create_crm_record", "description": "Create a CRM record from an AI Agent conversation.", "locations": ["VIRTUAL_AGENT"], "trigger_selection_type": "TRIGGER_ENDPOINT", "definition_type": 2, "standard_input_definition": { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "title": "Create CRM Record Input", "properties": { "title": { "type": "string", "title": "Title", "description": "Short title for the CRM record." }, "summary": { "type": "string", "title": "Summary", "description": "Conversation summary or context to include in the record." } }, "required": ["title"] }, "standard_output_definition": { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "title": "Create CRM Record Output", "properties": { "recordId": { "type": "string", "title": "Record ID", "description": "Unique identifier of the record created by the app." }, "recordUrl": { "type": "string", "title": "Record URL", "description": "Direct URL where the user can open the created record." } }, "required": ["recordId"] }, "endpoint_key": "create_crm_record", "input_mapping": [ { "param_key": "title", "required": true, "mapping_template": "{{input.title}}" }, { "param_key": "summary", "required": false, "mapping_template": "{{input.summary}}" } ], "output_mapping": [ { "param_key": "recordId", "mapping_template": "{{response.id}}" }, { "param_key": "recordUrl", "mapping_template": "{{response.url}}" } ] } ``` ## Script example Use script mode when your action logic is implemented directly in the manifest action. ```json { "name": "Summarize Case", "command_id": "summarize_case", "description": "Return a short summary for a support case.", "locations": ["VIRTUAL_AGENT"], "trigger_selection_type": "TRIGGER_ENDPOINT", "definition_type": 2, "standard_input_definition": { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "title": "Summarize Case Input", "properties": { "caseId": { "type": "string", "title": "Case ID", "description": "Unique identifier of the case to summarize." } }, "required": ["caseId"] }, "standard_output_definition": { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "title": "Summarize Case Output", "properties": { "summary": { "type": "string", "title": "Summary", "description": "Short human-readable summary of the case." } }, "required": ["summary"] }, "script": "return { summary: 'Case ' + input.caseId + ' is ready for review.' };" } ``` > **On script usage** > > Do not include `endpoint_key`, `input_mapping`, or `output_mapping` when using script. --- ## Field description | Field | Required | Description | | :--------------------------- | :--------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------- | | `enable` | No | Enables manifest-managed actions when `true`. Defaults to `true`. Set to `false` only if you want to disable manifest-managed actions for the app. | | `actions` | Yes | Array of action definitions. | | `name` | Yes | Display name for the action. Maximum 200 characters. Do not use names that start with `zoom_reserved`. | | `command_id` | Yes | Stable identifier for the action. Maximum 100 characters. Must be unique within the manifest payload. | | `description` | Recommended | Human-readable description of what the action does. Maximum 1000 characters. | | `locations` | Yes | List of Zoom locations where the action is available. Use only documented custom-action locations. | | `trigger_selection_type` | No | How the action is invoked. Use `TRIGGER_ENDPOINT` for Connect endpoint actions. | | `definition_type` | Recommended | Use `2` for standard JSON Schema input/output definitions. | | `standard_input_definition` | Recommended | JSON Schema describing the inputs the action accepts. | | `standard_output_definition` | Recommended | JSON Schema describing the outputs the action returns. Include clear descriptions for output fields. | | `endpoint_key` | Required for Connect endpoint mode | Connect endpoint key configured for your app. Do not include this in script mode. | | `input_mapping` | Required for Connect endpoint mode | Maps action inputs to the Connect endpoint request. | | `output_mapping` | No | Maps the Connect endpoint response to action outputs. Requires `input_mapping` when present. | | `script` | Required for script mode | Inline action handler. Do not include this with `endpoint_key`, `input_mapping`, or `output_mapping`. | --- ## Wiring rules Each custom action must use **exactly one** wiring mode. | Wiring mode | Include | Do not include | | :-------------------- | :--------------------------------------------------------- | :------------------------------------------------ | | Connect endpoint mode | `endpoint_key`, `input_mapping`, optional `output_mapping` | `script` | | Script mode | `script` | `endpoint_key`, `input_mapping`, `output_mapping` | --- ## Validation rules - `command_id` values must be unique in the `actions` array. - `locations` must contain at least one supported custom-action location. - `output_mapping` requires `input_mapping`. - Do not mix script mode and Connect endpoint mode in the same action. - `definition_type` can be `1`, `2`, or omitted. Use `2` for new actions. - `form_items` is only valid when `definition_type` is `2`. - For AI-powered locations, include clear `description` values in the `standard_output_definition` properties so Zoom can understand the data your action returns. - Do not include `built_in_config` for custom actions. --- ## Choosing a wiring mode - Use _connect endpoint_ mode when the action should call your app backend through a Connect endpoint. - Use _script_ mode for simple action logic that can run directly from the manifest action definition.