Skip to main content
AI Builder Automations Interface
Automations are the core server-side processes that power your AI Builder applications. They define what to do and when to do it, allowing you to create sophisticated workflows, integrate with external systems, and build intelligent applications.

Understanding Automations

  • What are Automations?
  • Automation Architecture
In simple words, automations describe what to do and when:
  • What to do: A sequence of instructions that process data and perform actions
  • When to do it: Triggers that activate the automation when specific conditions are met
Example:A HubspotDealsOnSlack automation might send a notification message on Slack every time a new Hubspot deal is created:
  • The what would be a fetch instruction calling Slack API to send a message
  • The when would be a URL (webhook) trigger that Hubspot calls whenever a new deal is opened

Triggers

Automations can be activated through different types of triggers, configured at the top of the automation graph:
When an automation activates its URL trigger, it becomes publicly available through a URL which you can copy from your Workspace graph or source code. You can then use this URL in external services that support webhooks.From inside the automation, 4 variables give access to input HTTP requests:
  • body: Request body
  • headers: Request headers
  • method: HTTP method (GET, POST, etc.)
  • query: URL query parameters
For multipart/form-data requests, uploaded files will be detailed within a body.<fileKey> object variable.
Example :
  {
    "originalname": "filename.pdf",
    "encoding": "7bit",
    "mimetype": "application/pdf",
    "size": 375966,
    "base64": "<file base 64>"
  }
By default, these HTTP requests will receive the automation output as a response body. However, an $http variable available inside the automation gives full control over the response:
- set:
    name: $http
    value:
      headers:
        content-type: application/json
      status: 200
You can also use this variable to implement Server-Sent Events (SSE) for streaming responses:
- set:
    name: $http
    value:
      chunk: # Data object that will be sent as an SSE event
        partial: "First part of response"
- set:
    name: $http
    value:
      chunk: # Another chunk
        partial: "Second part of response"
  • $http is only available in the URL-triggered automation (not in children calls)
  • Headers cannot be set after the first chunk is sent
  • When using SSE events, the automation output will also be sent as the last event
  • SSE automatically sets appropriate headers (Content-Type, Cache-Control, Connection)
For long-running SSE endpoints, you can configure a keep-alive to avoid timeouts:
- set:
    name: $http
    value:
      sseKeepAlive: 5000 # Keep-alive interval in milliseconds (minimum 5000ms)
After this instruction, a data: {"keepAlive": true} chunk will be regularly emitted until the connection ends.
An automation can listen to a list of events. Whenever such events are received, the automation is executed and can access:
  • payload: Event payload data
  • source: Event source information (source IP, correlationId, userId, automation, etc.)
These events can be:
  • Native events: Generated automatically by the platform
  • Custom events: Emitted from automations in the same workspace
  • App events: Emitted from installed Apps
Example configuration:
when:
  events:
    - user-login
    - document-uploaded
Workspaces can only listen to a specific subset of native events. See the Supported Native Events section for details.
An automation can be regularly triggered based on cron expressions:
when:
  schedules:
    - '0 9 * * 1-5' # Run at 9:00 AM on weekdays
  • Automations can be scheduled at most every 15 minutes
  • Schedules use UTC timezone
  • When scheduled, the automation runs “on the hour” (e.g., a 20-minute schedule starting at 3:14 will run at 3:20, 3:40, etc.)
  • When successfully scheduled, a runtime.automations.scheduled event is emitted
A helpful tool for creating cron expressions is crontab.guru.

Memory Architecture

Automations can use and modify data across different memory scopes:
Available only during current execution
Access pattern: {{run.variable}} Run variables include execution context like:
  • run.date: Current timestamp
  • run.ip: Client IP address
  • run.automationSlug: Current automation identifier
  • run.correlationId: Unique ID for tracing related events
  • run.depth: Current automation depth in the stacktrace
  • run.trigger.type: Trigger type (event, endpoint, automation)
  • run.trigger.value: Trigger value (event name, endpoint path, etc.)
  • run.socketId: Current socket ID if connected by websocket
  • run.appSlug: Current app slug if running from an appInstance
  • run.appInstanceSlug: Current appInstance slug if applicable
  • run.parentAppSlug: Parent app slug if parent is also an appInstance
The run context is automatically removed 60 seconds after the last automation run.
Persistent for the authenticated user
Access pattern: {{user.variable}}User variables include:
  • user.id: Unique user identifier
  • user.email: User’s email address
  • user.authData: Authentication information
  • user.role: User’s role in the workspace
  • Custom user-specific data that persists across sessions
Available for the current user session
Access pattern: {{session.variable}}Session variables include:
  • session.id: Current session ID
  • Custom session data
Session variables store temporary user data:
  • Form inputs across multiple steps
  • Wizard progress state
  • Temporary preferences
For authenticated users, session expiration is defined by the Gateway API (default 1 month). For unauthenticated endpoint calls, sessions expire after 1 hour of inactivity.
Shared across all users and executions
Access pattern: {{global.variable}}Global variables include:
  • global.workspaceId: Current workspace ID
  • global.workspaceName: Current workspace name
  • global.apiUrl: Current API instance public URL
  • global.studioUrl: Current studio instance public URL
  • global.pagesUrl: Current workspace pages public URL
  • global.pagesHost: Current pages instance base domain
  • global.endpoints: Map of available endpoint slugs to URLs
  • global.workspacesRegistry: Map of public workspaces
  • Custom workspace-wide variables
Available for the current websocket connection
Access pattern: {{socket.variable}}Socket scope provides a temporary state local to a websocket connection, useful for separating state between multiple browser tabs. This context automatically expires after 6 hours without any updates.
Workspace and app configuration
Access pattern: {{config.variable}}Contains the workspace configuration defined in the workspace settings.
Read-only workspace information
Access pattern: {{$workspace.variable}}This read-only context holds the current workspace definition, allowing access to any of its sections (e.g., installed apps config via $workspace.imports.myApp.config).
Except for $workspace, all these contexts can be written to using the set instruction. Written data will be persisted and available in subsequent requests. However, when setting variables inside session/user contexts from an unauthenticated webhook, they will not be persisted.

Working with Variables

Inside your automation instructions, dynamic data can be injected by surrounding a variable name with double braces: {{some.variable.name}}. Variables can be created and modified using the set instruction and removed using the delete instruction. For objects or arrays, you can access specific properties:
# Basic property access
{{user.profile.name}}

# Dynamic property access using another variable
{{session.myObjectVariable[{{item.field}}]}}
If session.myObjectVariable equals {"mickey": "house"} and item.field equals mickey, the entire expression resolves to house.

Instructions

Once triggered, automations execute a sequence of instructions in order. Here are the available instructions:

Logic Instructions

Conditionally execute instructions based on variable values or expressions.
- conditions:
    '{{user.age}} >= 18':
      - set:
          name: status
          value: adult
    '{{user.age}} < 18':
      - set:
          name: status
          value: minor
    default:
      - set:
          name: status
          value: unknown
More details on condition syntax
Loop through items or execute instructions multiple times.
# Iterate through an array
- repeat:
    on: '{{users}}'
    do:
      - set:
          name: processedUsers[]
          value: '{{item.name}}'

# Execute a fixed number of times
- repeat:
    until: 5
    do:
      - set:
          name: counter
          value: '{% {{$index}} + 1 %}'
You can also process batches in parallel:
- repeat:
    on: '{{workQueue}}'
    batch:
      size: 3  # Process 3 items by 3 items  in parallel
      interval: 500  # Pause 500ms between batches
    do:
      - process:
          item: '{{item}}'
Stop execution of the current automation or loop.
- break:
    scope: repeat  # Breaks out of the nearest repeat loop

- break:
    scope: automation  # Stops the current automation

- break:
    scope: all  # Stops all parent automations too
    payload:
      reason: "Operation cancelled"
When break is meant to be handled from a parent automation’s try/catch, scope must be set to all.If using the instruction like this : - break: {}, it will default to scope: automation.
Execute multiple operations in parallel.
- all:
    - automation1: {}
    - automation2: {}
    - fetch:
        url: https://api.example.com/data
Handle errors gracefully.
- try:
    do:
      - riskyOperation: {}
    catch:
      - set:
          name: errorInfo
          value: "{{$error}}"
      - emit:
          event: operation-failed
          payload:
            error: "{{$error}}"
The $error variable is accessible both inside and outside the catch block.

Data Instructions

Create or update variables in different scopes.
  • Basics
  • Objects
  • Array
# Simple variable assignment
- set:
    name: greeting
    value: "Hello, world!"

# Create or update object property
- set:
    name: user.profile.firstName
    value: "Jane"
Like everywhere else, you can also use expressions in the value parameter:
- set:
    name: counter
    value: '{% {{counter}} + 1 %}'
Remove variables when no longer needed.
- delete:
    name: temporaryData

Integration Instructions

Make HTTP requests to external APIs.
  • Basics
  • Output options
  • multipart/form-data
  • application/x-www-form-urlencoded
  • HTTP SSE (Server Side Events)
  • AWS SigV4
  # Basic GET request
  - fetch:
      url: https://api.example.com/users
      method: GET
      headers:
        Authorization: Bearer {{secret.apiToken}}
      output: apiResponse
  
  # POST request with JSON body
  - fetch:
      url: https://api.example.com/users
      method: POST
      body:
        name: "New User"
        email: "user@example.com"
      output: createResponse
Trigger events for UI updates or other automations.
  • Basics
  • Target
  • Options
- emit:
    event: user-registered
    payload:
      userId: "{{user.id}}"
      timestamp: "{{run.date}}"        
Pause execution until a specific event is received.
- emit:
    event: start-processing
    payload:
      documentId: "{{documentId}}"

- wait:
    oneOf:
      - event: processing-complete
        filters:
          payload.documentId: "{{documentId}}"
    timeout: 30  # Defaults to 20 seconds
    output: processingResult
Control resource usage with rate limiting.
- rateLimit:
    name: ExternalAPICall
    window: 60  # In seconds (1 minute)
    limit: 5    # Maximum 5 calls per minute
    consumer: "{{user.id}}"  # Per-user limit
    output: limits
- conditions:
    "{{limits.ok}}":
      - fetch:
          url: https://api.example.com/data
    default:
      - emit:
          event: rate-limit-exceeded
          payload:
            retryAfter: "{{limits.retryAfter}}"
            limit: "{{limits.limit}}"
            window: "{{limits.window}}"
            remaining: "{{limits.remaining}}"
            consumer: "{{limits.consumer}}"

Other Instructions

Generate authentication tokens for internal API calls. This token cannot be used outside of automations, and is specifically intented for fetch consumption (as an Authorization header).
- auth:
    workspace: true
    output: jwt
- fetch:
    url: https://api.studio.prisme.ai/v2/workspaces/123/webhooks/someAutomation
    headers:
      Authorization: Bearer {{jwt.jwt}}
    output: apiResponse
When fetching a Prismeai automation endpoint with such workspace token, a {{run.authenticatedWorkspaceId}} variable (which cannot be manually set) will be made available to securely check calling workspace.
You can also forward source workspace authentication to a subsequent fetch :
- fetch:
    url: https://api.studio.prisme.ai/v2/workspaces/123/webhooks/someAutomation
    auth:
      prismeai:
        forwardWorkspaceAuth: true
    output: apiResponse
Manage user subscription topics.User topics allow sending events to multiple users without knowing who they are in advance, automatically granting them read access to these events without requiring any API Key.
# Create a user topic
- createUserTopic:
    topic: project-updates
    userIds: 
      - "{{user1Id}}"
      - "{{user2Id}}"

# Add users to a topic
- joinUserTopic:
    topic: project-updates
    userIds: # Defaults to current user.id
      - "{{newUserId}}"
User topics allow sending events to multiple users without knowing who they are in advance.

Condition and Expression syntax

Conditions allow you to execute different instructions based on contextual information. You can use a powerful expression syntax in conditions and anywhere with {% ... %} delimiters.

Basic Operators

# Comparison operators
{{someAge}} > 18
{{someAge}} >= 18
{{someAge}} < 18
{{someAge}} <= 18
{{someAge}} == 18
{{someAge}} = 18
{{cityName}} = "Toulouse"

# Inequality
{{someAge}} !== 18
{{someAge}} != 18

# String matching
"hello" matches "hel"
"hello" matches {{someArray}}

# Variable checking
{{testedVariable}}      # Is this variable defined?
!{{testedVariable}}     # Is this variable empty?

# Membership testing
{{someValue}} in {{someList}}
{{someKey}} in {{someObject}}
{{someKey}} not in {{someObject}}
{{someKey}} not in "my,string,list"

# Type checking
isArray({{someVariable}})
isObject({{someVariable}})
isString({{someVariable}})
isNumber({{someVariable}})

Logical Operators

# AND operators
{{someAge}} >= 18 and {{cityName}} == "Toulouse"
{{someAge}} >= 18 && {{cityName}} == "Toulouse"

# OR operators
{{someAge}} >= 18 or {{cityName}} == "Toulouse"
{{someAge}} >= 18 || {{cityName}} == "Toulouse"

# Grouping with parentheses
{{someCity}} == "Paris" || ({{someAge}} >= 18 && {{cityName}} == "Toulouse")

# Negation
{{someCity}} == "Paris" || ! ({{someAge}} >= 18 && {{cityName}} == "Toulouse")
{{someCity}} == "Paris" || not ({{someAge}} >= 18 && {{cityName}} == "Toulouse")

Regular Expressions

"luke.skywalker@gmail.com" matches regex("luke|skywalker")
"luke.skywalker@gmail.com" matches regex(/luke|skywalker/)

MongoDB-like Conditional Matches

jsonmatch({{object}}, {{condition}})
Example condition:
{
  "$or": [
    {
      "test": "unknown"
    },
    {
      "one": {
        "$eq": "three"
      }
    }
  ]
}

Deep merge objects

This functiun helps deep merge two objects.
deepmerge({{firstObject}}, {{secondObject}})
It also accepts an option object which can slightly modify the merge behaviour.
deepmerge({{firstObject}}, {{secondObject}}, {{options}})
Example options:
{
  "concatStrings": true // Rather than replacing string from the same keys, concatenate them if possible.
}

Date Functions

Parsing and Access

date("2022-04-13T08:00:05.493Z").hour == 8
date({{mydate}}).minute > 34 && date({{mydate}}).minute < 37
date({{mydate}}).second >= 5
date({{mydate}}).date == 23
date({{mydate}}).month >= 6 && date({{mydate}}).month < 10
date({{mydate}}).year == 2022
date({{mydate}}).day == 3
date({{mydate}}).day in {{allowedDays}}
date({{mydate}}).ts == 1649836805493
date({{mydate}}).iso == '2022-04-13T08:00:05.493Z'
Note: Tested values are UTC based, and day starts on 0 for Sunday (so 3 is Wednesday).

Formatting

date("2023-03-31T17:07:23.975Z", "l") == "3/31/2023"
date("2023-03-31T17:07:23.975Z", "DD/MM/YYYY") == "3/31/2023"
date("2023-03-31T17:07:23.975Z", "LT") == "7:07 PM"
date("2023-03-31T17:07:23.975Z", "LT", "fr") == "19:07"
date("2023-03-31T17:07:23.975Z", "lll", "fr") == "31 mars 2023 19:07"
date("2023-03-31T17:07:23.975Z", "l LT") == "3/31/2023 7:07 PM"
date("2023-03-31T17:07:23.975Z", "LT", "fr", "America/New_York") == "13:07"
See all formatting options on Day.js documentation.

Math Functions

Operators

1+1
1+{{someVariable}}
{{firstVar}} * {{secondVar}}
({{firstVar}} * {{secondVar}} + 10) / 2

Functions

rand(50, 150)  # Random number between 50 and 150
rand()  # Random float between 0 and 1

round(10.2)  # 10
round(10.2, 1)  # 10.2
round(10.26, 1)  # 10.3

ceil(10.1)  # 11
ceil(10.9)  # 11

String Functions

# convert string to lower case
lower({{foo}})

# convert string to upper case
upper({{foo}})

# Truncate string
truncate({{str}})
truncate({{str}}, 42)
truncate({{str}}, 42, ' etc')
truncate({{str}}, {{len}}, {{ellipsis}})

# JSON parsing/stringifying
json('{"foo": "bar"}')  # Object { foo: "bar" }
json({"foo": "bar"})  # String '{"foo":"bar"}'

# Unsafe JSON parsing: never raises exception, try to extract a JSON object or array when surrounded by other text
unsafejson('Voici un tableaux: ["un"] !') # ["un"]
unsafejson('Voici un objet :\n ```{"un": 1}```\n !') # {"un": 1}

# String manipulation
split('one,two,three', ',')  # Array ["one", "two", "three"]
join(['one', 'two', 'three'], ',')  # String "one,two,three"
replace('hello world', 'world', 'there')  # String "hello there"

# Sanitize html
sanitize('<b>Bonjour <u>toi</u></b> !') # &#60;b&#62;Bonjour &#60;u&#62;toi&#60;/u&#62;&#60;/b&#62; !

# Remove complex unicode characters (non BMP, non UTF16 surrogates)
sanitize('Bonjour 🌍 ! Ça va ? 我爱你 ❤️') # Bonjour  ! Ça va ? 我爱你 ❤️

URL parsing

Parse URL search params :
URLSearchParams("key1=value1&key2=value2").asJSON  # Object
URLSearchParams({foo: "bar", abc: "xyz"}).asString  # String "foo=bar&abc=xyz"
Or parse a complete URL as an object :
URL("https://user:password@www.google.fr/some/path/?query=string&foo=bar#anchor")
This returns :
{
  href: 'https://user:password@www.google.fr/some/path/?query=string&foo=bar#anchor',
  origin: 'https://www.google.fr',
  protocol: 'https:',
  username: 'user',
  password: 'password',
  host: 'www.google.fr',
  hostname: 'www.google.fr',
  port: '',
  pathname: '/some/path/',
  search: '?query=string&foo=bar',
  searchParams: { "query": "string", "foo": "bar" },
  hash: '#anchor'
}
Or directly access a specific field :
URL("https://user:password@www.google.fr/some/path/?query=string&foo=bar#anchor").hostname # www.google.fr

Arguments

When calling a native instruction or another automation, different arguments can be transmitted. These graphical inputs are not reserved to native instructions, but can also be configured for your own custom automations by specifying expected arguments and their types.
testArguments:  
  do: []  
  name: testArguments
  arguments:
    someString:
      type: string
    someNumber:
      type: number
    someObject:
      type: object
      properties:
        someStringField:
          type: string
    someOtherObject:
      type: object
      properties:
        nestedObject:
          type: object
          properties:
            someField:
              type: number
    someStringArray:
      type: array
      items:
        type: string
    someObjectArray:
      type: array
      items:
        type: object
        properties:
          fieldA:
            type: string
    someRawJSON:
      type: object
      additionalProperties: true          
    someToken:
      type: string        
      secret: true
The someToken argument defined with secret: true is automatically redacted from native runtime events to avoid accidental leaks of sensitive information.

Arguments Validation

Automation arguments can be validated during execution by enabling validateArguments: true:
slug: test
name: test
do: []
when:
  endpoint: true
output: '{{body}}'
arguments:
  body:
    type: object
    required:
      - str
    properties:
      str:
        type: string
      uri:
        type: string
        format: uri
      obj:
        type: object
        required:
          - un
        properties:
          un:
            type: string
            pattern: '^[a-z]+$'
validateArguments: true
Arguments support various validation formats including date, url, time, password, etc. Validation errors immediately stop current and parent automations.

Advanced Automation Patterns

  • Webhook Handling
  • Data Processing Pipeline
  • Multi-LLM Orchestration
Implement secure webhook endpoints for third-party integrations:
# Webhook automation
slug: hubspot-webhook
name: Hubspot Deal Created
when:
  endpoint: true
do:
  # Validate webhook signature
  - conditions:
      '!{{headers["x-hubspot-signature"]}}':
        - set:
            name: $http
            value:
              status: 401
        - break:
            scope: automation
  
  # Process webhook data
  - set:
      name: newDeal
      value: "{{body.deal}}"
  
  # Notify team on Slack
  - fetch:
      url: "{{config.slackWebhookUrl}}"
      method: POST
      body:
        text: "New deal created: {{newDeal.name}} ({{newDeal.amount}})"
      output: slackResponse
  
  # Return success response
  - set:
      name: output
      value:
        success: true
        message: "Webhook processed successfully"

Supported Native Events

Workspaces can listen to a specific subset of native events:

Best Practices

Create maintainable automation structures:
    Break complex flows into smaller automationsUse events for communication between modulesCreate reusable patterns for common tasksDocument automation purposes and interfaces
Build robust fault tolerance:
    Use try/catch blocks for risky operationsImplement appropriate retry strategiesProvide informative error messagesCreate fallback paths for critical operations
Handle data appropriately across scopes:
    Use appropriate memory scopes for different data needsClean up temporary variables when finishedInitialize variables before using themBe mindful of persistence requirements
Keep your automations secure:
    Store sensitive data in secretsValidate inputs from external sourcesImplement rate limiting for external APIsUse proper authentication for API calls
Ensure efficient execution:
    Use parallel processing for independent operationsImplement batching for large data setsCache results when appropriateMonitor execution times and optimize bottlenecks
Validate automation functionality:
    Test with representative data samplesVerify error handling pathsTest edge cases and unexpected inputsUse Activity view to review execution history

Next Steps

Learn about UI components that trigger automations
Discover how to create interfaces for your applications
Learn more about deployment strategies
I