Reference

App YAML

On this page

Top-level structure of an app YAML.

Skeleton

name: ticket            # required, lowercase identifier
label: Support ticket   # required, display name
description: |          # optional, long-form description
  Ticket app for ...
icon: support           # optional, icon name (defaults to "support")

settings:               # optional, operational config
  ...
roles:                  # optional, who can do what
  ...
texts:                  # optional, UI text overrides
  ...

attributes:             # required, ≥1 attribute, must include "title"
  - name: title
    type: string
    label: Subject
    mandatory: true

triggers:               # optional
  - onCreate: [...]
    onComment: [...]
    onEdit: [...]
    onConclude: [...]

scripts:                # optional, named Starlark functions
  - name: route
    source: |
      def onTrigger(activity, conclude, trigger):
          ...

emailConnector: {...}   # optional
webConnector: {...}     # optional
jira: {...}             # optional
zendesk: {...}          # optional
lookup: {...}           # optional

create: {...}           # optional, controls activity creation UX
connect: {...}          # optional, connected-app mode
review: {...}           # optional, review workflow

Top-level fields

YAML keyTypeRequiredPurpose
namestring✓Unique identifier; lowercased on save
labelstring✓Display name
typechannel | global—App scope; defaults to channel
descriptionstring—Long description, shown in editor
contextstring—Extra contextual metadata (used by agents as system-prompt prefix)
iconstring—Icon name; defaults to support
settingsobject—See settings
rolesobject—See Macros and roles
textsobject—See texts
createobject—See create
connectobject—Connected-app linkage
reviewobject—See review
attributeslist✓See Attributes
triggerslist—See Triggers
scriptslist—See Scripting (Starlark)
emailConnectorobject—See Connectors
webConnectorobject—See Connectors
jira, zendeskobject—See Connectors
lookupobject—See Connectors

Validation rules

Conclude rejects an app that breaks one of these rules:

  • name and label must be non-empty
  • attributes must be non-empty
  • Attribute name must be unique
  • An attribute named title is mandatory and must have type: string
  • If an attribute named conclusion exists, it must have type: text

Settings

settings: holds the app’s operational configuration:

YAML keyTypePurpose
subjectstringSingular noun for an activity (“ticket”, “incident”); used in default UI text
modestringSpace-separated flags: channel (give each activity its own channel), silent (suppress chat notifications)
channelNamestringTemplate for per-activity channel names (supports macros). Example: _${__channel}_${jira.id}
notificationsstringdefault or a comma list (e.g. deadline,severity) — which lifecycle events post to chat
alertstringRole expression for channels/users to notify on every activity event
errorLogstringChannel for system error messages from this app
rateLimitstringN/min format; default 10/min for inbound connector traffic
disableDeadlineboolHides the built-in deadline attribute

Examples:

settings:
  subject: incident
  mode: channel               # each incident gets its own channel
  channelName: inc-${title}
  alert: ${__channel} ${initiator}
  notifications: deadline,severity
  rateLimit: 30/min

Texts

texts: overrides UI text. Set only the keys you want to change; everything else falls back to defaults that read naturally for the settings.subject you set.

Keys (all string, optional): launchButton, ownerLabel, unassignedLabel, unassignedAvatar, initiatorSummary, closedBySummary, createCaption, editCaption, concludeCaption, createIntro, editIntro, concludeIntro, createButton, editButton, concludeButton, externalUser, externalAvatar.

Example:

texts:
  createCaption: Report a new bug
  createButton: File bug
  concludeCaption: Close this bug

Create

create: controls how a user opens a new activity from chat.

YAML keyTypePurpose
reactionstringEmoji shortcut(s) that open the create form, comma-separated. Default: 🎫
userInputboolIf true, show the form before creating; otherwise create immediately
threadHistorypartial | fullHow much of a thread a reaction copies into the activity. Default: partial
create:
  reaction: ":bug:,:beetle:"
  userInput: true
  threadHistory: full

threadHistory: partial starts at the reacted message and skips everything before it in the thread. full copies the whole thread, starting at the parent message, no matter which reply carries the reaction. Either mode copies at most 100 messages. An unknown value is rejected when the app is saved.

Either way the copy keeps posts by other apps’ bots, matching what gets recorded when the messages arrive live. Everything posted through Conclude is skipped: banners and cards, agent posts, and messages Conclude relayed on behalf of a user in a bridged or connected channel.

Review

review: gates activities behind a review step.

YAML keyTypePurpose
membersstringRole expression for reviewers
alertstringChannel/users alerted when a pending review arrives
ignorestringSkip review for matching initiators (e.g. internal)
includestringForce review for matching initiators (e.g. external)
createChannelboolCreate a dedicated review channel per pending activity

Connect

connect: is for cross-org connected apps. Most apps don’t set this.