Actions

Action represents a single request or query your application wants to make in an external application. For example, "Create a task", "Get list of users", or "Send a message".

Here is an example of an action:

name: Create Task
key: create-task
inputSchema:
  type: object
  properties:
    title:
      type: string
    description:
      type: string
type: create-data-record
config:
  dataSource:
    collectionKey: issues
  fieldMapping:
    defaultValue:
      summary:
        $var: $.input.title
      description:
        $var: $.input.description

Action Structure

Task definition has the following top-level properties:

  • name – human-readable name that will be shown in the UI.
  • key – unique identifier used by SDK / API to reference the action.
  • inputSchemaData Schema describing the payload that will be validated when you run the action.
  • type – one of the Action Types (see table below).
  • config – implementation of the action. Its contents depends on the type.
  • outputSchema - defines expected output of the action. It will normally be auto-generated from the implementation, but you can define it explicitly.

Action Types

Actions let you run any synchronous logic against external APIs, your internal API, or just transforming inputs into outputs. Here is how actions let you use other Membrane interfaces:

Data Collection Actions

These action types give you access to functionality of Data Collections. All data actions share common configuration parameters documented in the Common Data Action Parameters section.

TypeDescription
list-data-recordsList records in a data collection page by page
find-data-record-by-idFind a record in a data collection by ID
search-data-recordSearch data records by a query string
match-data-recordFind a data record with fields matching a query
create-data-recordCreate a new data record
update-data-recordUpdate an existing data record
find-or-create-data-recordCombines "match data record" with "create data record" with optional use of Data Links
delete-data-recordDelete a data record by id

Common Data Action Parameters

All data actions use the following configuration structure:

config:
  dataSource: # Required: Data source configuration
    collectionKey: string # Required: Data collection identifier
    udm: string # Optional: Unified Data Model identifier
    collectionParameters: # Optional: Collection-specific parameters
      param1: value
    pullUpdatesIntervalSeconds: number # Optional: Sync interval for updates
    fullSyncIntervalSeconds: number # Optional: Full sync interval
  fieldMapping: # Optional: Field mapping configuration
    exportValue: # Optional: Your app → External app mapping
      externalField:
        $var: $.input.appField
    importValue: # Optional: External app → Your app mapping
      appField:
        $var: $.externalField
    defaultUnifiedValue: # Optional: Unified field mapping
      unifiedField:
        $var: $.input.value
    includeRawFields: boolean # Optional: Include raw external fields
  parameters: # Optional: Action-specific parameters
    param1: value

Field Descriptions:

  • dataSource - configuration for where to read/write data from/to
    • collectionKey - Identifier of the data collection to operate on
    • collectionParameters - Parameters passed to the collection methods
    • udm - (for universal integrations only) Universal Data Model to read/write.
  • fieldMapping - configuration for mapping fields from/to data collection
    • exportValue - Maps fields from your app to the external app format
    • importValue - Maps fields from external app to your app format
    • defaultUnifiedValue - (for universal integrations only) Default values for unified field mapping
  • parameters - Method-specific parameters

list-data-records

Returns a list of all data records in a collection, page by page.

name: List Tasks
key: list-tasks
type: list-data-records
config:
  dataSource:
    collectionKey: tasks
  fieldMapping:
    importValue:
      title:
        $var: $.summary
      createdAt:
        $var: $.created
  # Optional: filtering and pagination
  filter:
    status: open
  unifiedFilter:
    assigneeId:
      $var: $.input.userId
  cursor:
    $var: $.input.cursor

Additional Parameters:

  • filter - Filter criteria (values for specific fields that should be matched to return a record)
  • cursor - Pagination cursor for next page

Output Schema:

type: object
properties:
  cursor:
    type: string
  records:
    type: array
    items:
      type: object # Based on field mapping configuration

find-data-record-by-id

Finds a record in a data collection by its ID.

name: Find Task
key: find-task
type: find-data-record-by-id
config:
  dataSource:
    collectionKey: tasks
  fieldMapping:
    importValue:
      title:
        $var: $.summary
  # Required: record ID
  id:
    $var: $.input.taskId

Additional Parameters:

  • id - Record ID to find (supports formulas)

Output: Single record object or null if not found

search-data-record

Searches records in a data collection using a text query.

name: Search Tasks
key: search-tasks
type: search-data-record
config:
  dataSource:
    collectionKey: tasks
  fieldMapping:
    importValue:
      title:
        $var: $.summary
  # Required: search query
  query:
    $var: $.input.searchText
  cursor:
    $var: $.input.pageToken

Additional Parameters:

  • query - Search query string
  • cursor - Pagination cursor

Output Schema:

type: object
properties:
  cursor:
    type: string
  records:
    type: array
    items:
      type: object

match-data-record

Finds a data record with fields matching specific criteria.

name: Find Task by Title
key: match-task
type: match-data-record
config:
  dataSource:
    collectionKey: tasks
  fieldMapping:
    importValue:
      title:
        $var: $.summary
  # Search criteria
  lookup:
    universalQuery:
      title:
        $var: $.input.title
    query:
      status: active

Additional Parameters:

  • lookup.universalQuery - Unified query fields
  • lookup.query - Native app query fields
  • query (deprecated) - Use lookup.universalQuery instead

Output: Single matching record or null if not found

create-data-record

Creates a new data record.

name: Create Task
key: create-task
inputSchema:
  type: object
  properties:
    title:
      type: string
    description:
      type: string
type: create-data-record
config:
  dataSource:
    collectionKey: tasks
  fieldMapping:
    exportValue:
      summary:
        $var: $.input.title
      description:
        $var: $.input.description
      status: "open"

Output Schema:

type: object
properties:
  id:
    type: string

update-data-record

Updates an existing data record by ID.

name: Update Task
key: update-task
inputSchema:
  type: object
  properties:
    title:
      type: string
    status:
      type: string
type: update-data-record
config:
  dataSource:
    collectionKey: tasks
  fieldMapping:
    exportValue:
      summary:
        $var: $.input.title
      status:
        $var: $.input.status
  # Required: record ID
  id:
    $var: $.input.taskId

Additional Parameters:

  • id - Record ID to update (supports formulas)

Output Schema:

type: object
properties:
  id:
    type: string

find-or-create-data-record

Combines match and create operations - finds a matching record or creates a new one.

name: Find or Create Contact
key: find-or-create-contact
type: find-or-create-data-record
config:
  dataSource:
    collectionKey: contacts
  fieldMapping:
    exportValue:
      email:
        $var: $.input.email
      firstName:
        $var: $.input.firstName
  # Match criteria
  lookup:
    universalQuery:
      email:
        $var: $.input.email
  # Optional: data linking
  dataLink:
    dataLinkTableKey: "contact-links"
    appRecordId:
      $var: $.input.userId

Additional Parameters:

  • lookup - Same as match-data-record
  • dataLink.dataLinkTableKey - Data link table reference
  • dataLink.appRecordId - App record ID for linking

Output Schema:

type: object
properties:
  id:
    type: string

delete-data-record

Deletes a data record by ID.

name: Delete Task
key: delete-task
type: delete-data-record
config:
  dataSource:
    collectionKey: tasks
  # Required: record ID
  id:
    $var: $.input.taskId

Additional Parameters:

  • id - Record ID to delete (supports formulas)

Output Schema:

type: object
properties:
  id:
    type: string

API Request Actions

connector-operation

Uses API Operations from the current connector.

name: Add Attachment
key: add-attachment
inputSchema:
  type: object
  properties:
    issueId:
      type: string
    fileUrl:
      type: string
type: connector-operation
config:
  operationKey: add-attachment-to-an-issue
  input:
    issueIdOrKey:
      $var: $.input.issueId
    fileUrl:
      $var: $.input.fileUrl

Configuration Parameters:

  • operationKey - Operation identifier from connector (required)
  • input - Input data for the operation (optional)

Output: Operation-specific output based on connector operation schema

api-request-to-external-app

Makes arbitrary API requests to the API of the current external app with authentication applied automatically.

name: Create Issue
key: create-issue
inputSchema:
  type: object
  properties:
    projectId:
      type: string
    title:
      type: string
    priority:
      type: string
type: api-request-to-external-app
config:
  request:
    path: /projects/{projectId}/issues
    method: POST
    pathParameters:
      projectId:
        $var: $.input.projectId
    query:
      notify: true
    data:
      summary:
        $var: $.input.title
      priority:
        $var: $.input.priority
    headers:
      X-API-Version: "2025-01-01"
      Content-Type: application/json
  responseSchema:
    type: object
    properties:
      id:
        type: string
      key:
        type: string
  allowNon2xx: false

Configuration Parameters:

  • request.path - API endpoint path (supports {paramName} substitution)
  • request.method - HTTP method (GET, POST, PUT, DELETE, etc.) - defaults to GET
  • request.pathParameters - Path parameter substitutions
  • request.query - Query parameters
  • request.data - Request body
  • request.headers - Additional headers
  • responseSchema - Expected response schema (optional)
  • allowNon2xx - Allow non-200 responses (default: false)

Output Schema:

type: object
properties:
  status:
    type: number
  data:
    # Based on responseSchema or generic object

api-request-to-your-app

Makes API requests to your Internal API.

name: Notify Internal System
key: notify-internal
inputSchema:
  type: object
  properties:
    userId:
      type: string
    message:
      type: string
type: api-request-to-your-app
config:
  request:
    uri: /notifications
    method: POST
    body:
      userId:
        $var: $.input.userId
      message:
        $var: $.input.message
    headers:
      Content-Type: application/json
  batchSize: 10

Configuration Parameters:

  • request.uri - Internal API endpoint URI
  • request.method - HTTP method (defaults to GET)
  • request.body - Request body
  • request.query - Query parameters
  • request.headers - HTTP headers
  • batchSize - Batch processing size (optional)
  • responseSchema - Expected response schema (optional)
  • allowNon2xx - Allow non-200 responses (optional)

Output Schema:

type: object
properties:
  response:
    type: object
    properties:
      status:
        type: integer
      data:
        # Based on responseSchema

http-request

Makes arbitrary HTTP requests to any endpoint.

name: Call External API
key: call-external-api
inputSchema:
  type: object
  properties:
    endpoint:
      type: string
    apiKey:
      type: string
type: http-request
config:
  request:
    uri:
      $var: $.input.endpoint
    method: GET
    headers:
      Authorization:
        $formula: "Bearer " + $.input.apiKey
      Content-Type: application/json
    query:
      limit: 100
  responseSchema:
    type: object
    properties:
      data:
        type: array
  allowNon2xx: false

Configuration Parameters:

  • request.uri - Request URI (required)
  • request.method - HTTP method (defaults to GET)
  • request.body - Request body
  • request.query - Query parameters
  • request.headers - HTTP headers
  • responseSchema - Expected response schema (optional)
  • allowNon2xx - Allow non-200 responses (optional)

Output Schema:

type: object
properties:
  status:
    type: integer
  data:
    # Based on responseSchema or generic object

Code Execution Actions

run-javascript

Runs custom JavaScript (or TypeScript) code.

name: Process Data
key: process-data
inputSchema:
  type: object
  properties:
    items:
      type: array
type: run-javascript
config:
  code: |-
    module.exports = async function(variables, connectorExecutor) {
      const { items } = variables.input;
      
      // Process the data
      const processed = items.map(item => ({
        ...item,
        processed: true,
        timestamp: new Date().toISOString()
      }));
      
      // Make external API call if needed
      const response = await connectorExecutor.execute({
        operationKey: 'update-status',
        input: { count: processed.length }
      });
      
      return {
        processed,
        status: response.success
      };
    }
  outputSchema:
    type: object
    properties:
      processed:
        type: array
      status:
        type: boolean

Configuration Parameters:

  • code - JavaScript code to execute (required)
  • outputSchema - Expected output schema (optional)

Execution Context:

  • variables - Input variables including action input
  • connectorExecutor - For making connector API calls
  • Sandboxed execution environment

Output: Dynamic based on outputSchema or {} if not specified

See Running Custom Code for more detail.

Action Implementation Guide

If you are an AI agent, use this guide to populate your ToDo list when implementing an action.

Try every option below in order. If earlier option does not work - move on to the next option. If you chose an option but it ended up not implement the action correctly - move on to the next option.

  • If the action potentially matches one of the Data Collection methods (i.e. list, create, etc) - find the corresponding data collection for the current integration and see if it has the corresponding method. If found - use the corresponding action type (i.e. list-data-records, create-data-record, etc)
    • Check if data collection and method have all the necessary inputs/outputs. If not - ignore this option.
  • If the action could potentially be implemented with a single API request (it is not a multi-step action) - find out if a corresponding API is available. If so - use api-request-to-external-app type.
  • If none of the above worked - use run javascript type. Make requests to API docs to see what's available.

References