Skip to content
Last updated

Actions

Actions are API calls that users (or automations) can execute. Each action has a form for user input, one or more HTTP requests, and response mapping.

Defining an Action

actions: [
  {
    name: 'createIssue',              // Unique action identifier
    title: 'Create Issue',            // Display title
    description: 'Create a new issue in a repository',
    renderStrategy: 'auto',           // UI rendering ('auto' = standard form)

    // Form definition (JSON Schema)
    parameters: { /* see §5.2 */ },

    // HTTP requests to execute (see §5.3)
    requests: [ /* ... */ ],
  },
]

renderStrategy values:

ValueDescription
'auto'Standard auto-generated form (recommended)

Parameters (JSON Schema)

Parameters define the user-facing form using JSON Schema. Extended with custom x-* properties for dynamic data.

parameters: {
  type: 'object',
  required: ['repository', 'title'],
  properties: {
    // Simple text input
    title: {
      type: 'string',
      title: 'Issue Title',
      description: 'A short descriptive title',
    },

    // Text area (multiline)
    body: {
      type: 'string',
      title: 'Description',
    },

    // Dynamic dropdown from RPC source
    repository: {
      type: 'string',
      title: 'Repository',
      'x-source': 'rpc_repos_list',   // References a source definition
      'x-fallback': 'input',           // Fallback to text input if source fails
    },

    // Static dropdown (enum)
    priority: {
      type: 'string',
      title: 'Priority',
      enum: ['low', 'medium', 'high', 'critical'],
      default: 'medium',
    },

    // Boolean toggle
    isDraft: {
      type: 'boolean',
      title: 'Draft',
      default: false,
    },

    // Number input
    count: {
      type: 'number',
      title: 'Count',
    },

    // Array input (comma-separated or JSON)
    labels: {
      type: 'array',
      title: 'Labels',
    },
  },
}

Supported type values:

TypeRendered As
stringText input (or dropdown if enum provided)
numberNumber input
booleanToggle switch
arrayMulti-value input
objectNested form group

Custom extensions:

ExtensionTypeDescription
x-sourcestringRPC source key (e.g., 'rpc_channels_list')
x-fallbackstringFallback mode if source fails ('input')

Requests & Chaining

Each action has a requests array. Requests execute sequentially — the response from request N is available as placeholders in request N+1.

Single request:

requests: [
  {
    url: 'https://api.example.com/issues',
    method: 'POST',
    headers: {
      Authorization: 'Bearer [[accessToken]]',
      'Content-Type': 'application/json',
    },
    bodyType: 'json',
    body: {
      title: '{{title}}',
      body: '{{body}}',
      labels: '{{labels}}',
    },
    mapping: {
      issueId: '$.id',
      issueUrl: '$.html_url',
    },
  },
]

Chained requests (multi-step):

// Example: Send a direct message on Slack
// Step 1: Open a DM channel with the user
// Step 2: Post a message to that channel
requests: [
  // Step 1: Open DM channel
  {
    url: 'https://slack.com/api/conversations.open',
    method: 'POST',
    headers: {
      Authorization: 'Bearer [[accessToken]]',
      'Content-Type': 'application/json',
    },
    bodyType: 'json',
    body: { users: '{{userId}}' },
    // Array mapping → values forwarded to next request (NOT persisted)
    mapping: [
      { name: 'dmChannelId', value: '$.channel.id' },
    ],
  },

  // Step 2: Post message (uses dmChannelId from step 1)
  {
    url: 'https://slack.com/api/chat.postMessage',
    method: 'POST',
    headers: {
      Authorization: 'Bearer [[accessToken]]',
      'Content-Type': 'application/json',
    },
    bodyType: 'json',
    body: {
      channel: '{{dmChannelId}}',    // ← From step 1's mapping
      text: '{{messageText}}',       // ← From user's form input
    },
    mapping: {
      messageTs: '$.ts',
      channelId: '$.channel',
    },
  },
]

Request fields:

FieldTypeRequiredDescription
urlstringFull URL (supports [[cred]] and {{param}})
methodstringHTTP method: GET, POST, PUT, PATCH, DELETE
headersobjectRequest headers
queryParamsobjectURL query parameters
bodyTypestring'json', 'x-www-form-urlencoded', 'formData'
bodyobjectRequest body (placeholders replaced at runtime)
mappingobject or arrayResponse extraction (see §5.5)

Placeholders

There are two placeholder syntaxes:

SyntaxSourcePersisted?Example
[[key]]credentials + metadataN/A[[accessToken]], [[storeId]]
{{key}}User input + runtime contextNo{{channel}}, {{store_url}}

Placeholder resolution order for {{key}}:

  1. User's form input (parameters)
  2. Previous request's mapping output (in chained requests)
  3. auth.config values (for registration requests)
  4. System-injected values (webhookUrl, subdomain, uid)

Type preservation: If a placeholder is the entire value (e.g., body: { data: '{{myObject}}' }), the raw type is preserved — objects remain objects, arrays remain arrays. If a placeholder is part of a larger string (e.g., "Hello {{name}}!"), it's stringified.

Response Mapping

Mapping extracts values from API responses. Two formats with different behaviors:

Object mapping — Values are persisted in the database:

Auth stepStored in
get_token, refresh_token, registrationRequestsInstalledMiniApps.credentials
userDetailsInstalledMiniApps.metadata (full mapping preserved)
// get_token / refresh_token / registrationRequests → credentials
mapping: {
  accessToken: '$.access_token',
  webhookId: '$.webhook.id',
}

// userDetails → metadata
mapping: {
  uid: '$.user.id',
  storeId: '$.user.store.id',
  storeName: '$.user.store.title',
}

Use object mapping in get_token, refresh_token, registrationRequests, and userDetails.

Array mapping — Values are forwarded to the next request only (not persisted):

mapping: [
  { name: 'channelId', value: '$.channel.id' },
  { name: 'threadTs', value: '$.message.ts' },
]

Use array mapping in action requests when you need to chain request outputs.

Dot-path syntax: Values use JSONPath-like syntax starting with $:

ExpressionDescription
$.idRoot-level id field
$.data.user.nameNested access
$.items[0].codeArray index access
$.channelDirect field reference