Reference Documentation

Contents Commands Methods



Basic Guide

This guide introduces the basic statements and building blocks used in Streamscript. If you have experience with Salesforce Formulas, you'll find this straightforward.

Comments begin with a hash # sign.

# Streamscript

Variables begin with a dollar $ sign and are case sensitive. Use an equals = sign to set values.

$account = 'GenePoint'Try

Data types are text, number, boolean, list, and map, like JSON.

$text = 'Hi!'
$number = 12345
$boolean = false
$list = ['GenePoint', 'GenWatt']
$map = {LastName: 'Smith', AccountId: '001000000000000AAA'}Try

Templates are text in ` backticks. You can embed $variables and ${expressions} in templates.

$author = 'Mark Twain'
$quote = 'Reports of my death are greatly exaggerated'
Log `$author - "$quote"` # Mark Twain - "Reports of my death are greatly exaggerated"Try

Operators are used to compare variables and make formulas.

$profit = $sales - $costs
$success = $profit > 10000
$vacation = $success and $weather == 'sunny'Try

Methods operate on any variable using the call .() operator. Parentheses are optional.

$greeting = 'Hello World'
$length = $greeting.length             # 11
$shortGreeting = $greeting.left(5)     # Hello
$loudGreeting = 'Hello World'.upper    # HELLO WORLDTry

Commands are actions. Each command runs by itself, unlike methods which act on a variable.
They can be accompanied by one or more parameters separated by spaces - not commas.

Log 'I had no idea Abraham Lincoln loved cats.' # Logs appear in the sidebarTry

Decisions use the switch and if keywords. For alternative branches use elseif and else.

if ($weather == 'sunny')
    # run if weather is sunny

switch ($weather)
    hot { ... } # run when weather is hot
    cold { ... } # run when weather is cold
    default { ... } # run when weather is anything else

# if-else in one line (ternary operator)
$ticket = $age > 18 ? 'Adult' : 'Child'
$dealtype = $staff < 100 ? 'SMB' : 'Enterprise'Try

Loops repeat the logic between the { curly } braces. Streamscript supports while, foreach, for and do-while loops. Use continue to skip an iteration, or break to terminate the loop.

$condition = false
while ($condition)
    # runs while condition is true

$items = [1, 2, 3, 4, 5]
foreach ($item in $items)
    # loops over all the items in the list

Merge Fields also known as formula tags are used to import flow resources including flow constants, flow globals, flow variables, records, and collections.  

$var = {!var}
$const = {!constant}
$formula = {!formula}
$Opportunity = {!$Record}Try


Ready for powerful commands like HTTP callouts? Try the advanced examples below!








HTTP commands

# Send a GET or POST request 
$Http = Http-Get $url $headers
$Http = Http-Post $url $headers $body
$Http = Http-Post $url $headers $body -base64
$Http = Http-Patch $url $headers $body
$Http = Http-Put $url $headers $body
$Http = Http-Delete $url $headers $body
# optional base64 flag treats the request and response body as encoded binary data

# Response map
$Http.body       # Represents the text of the body returned in the response
$Http.status     # Represents the integer status code returned in the response
$Http.headers    # Represents the map of HTTP headers returned in the responseTry


We recommend using the secure fields of Named Credentials as a best practice:

# Streamscript to call the Kentaa Payments API
$url = 'callout:https_api_kentaa_nl/v1/actions'
$headers.Api-Key = {!$Credential.Password}
$Http = Post $url $headers $payload


Date/Time commands

# Return the text value representing a datetime, eg '2022-12-24T23:59:59.999Z'
$dt = Datetime-Value $year $month $day $hour $minute $second $millis -gmt

# Return the text value representing a date, eg '2022-12-24'
$date = Date-Value $year $month $day

# Return the text value representing a time, eg '23:59:59.999Z'
$time = Time-Value $hour $minute $second $millis

# Return the time zone offset (in milliseconds) between the datetime and GMT
$millis = Timezone-Offset $timezoneId $datetime


Business Hours commands

# Add a time interval to the start datetime, adjusting for business hours
$dt = BusinessHours-Add $businessHoursId $startDatetime $intervalMillis -gmt

# Return the number of milliseconds between two datetimes, adjusting for business hours
$int = BusinessHours-Diff $businessHoursId $startDatetime $endDatetime

# Return true if the target datetime occurs within business hours, accounting for holidays
$bool = BusinessHours-IsWithin $businessHoursId $targetDatetime

# For the target datetime, return next datetime when business hours are open, accounting for holidays
$dt = BusinessHours-NextStartDate $businessHoursId $targetDatetime


Encode/Decode commands

# Convert the variable to JSON text and vice versa
$text = Json-Encode $var
 $var = Json-Decode $text

# Convert the variable to CSV text and vice versa
$text = Csv-Encode $listOfRows
$rows = Csv-Decode $text

# Convert unsafe characters to URL-safe percent encoded format and vice versa
$code = Url-Encode $text
$text = Url-Decode $code

# Convert the Base64 encoded binary value to text and vice versa
$text = Base64-Decode $b64
 $b64 = Base64-Encode $text


Record commands

# Prepare a record using a map or parameters
$Account = New-Account {Name: 'ACME'}
$Contact = New-Contact -LastName 'Smith'
$CustomObject__c = New-CustomObject__c -Id $record_id_here
$nsprefix__PackagedObject__c = New-nsprefix__PackagedObject__c Try
# Query a record or records
$Account = Query-Record `SELECT Name FROM Account WHERE Id = '$id'`
$Contacts = Query-Records `SELECT Name FROM Contact WHERE AccountId = '$id'`Try


Info commands

# Current user information
$id = User-Info -id                    # Return the user's ID
$name = User-Info -name                # Return the user's full name
$email = User-Info -email              # Return the user's email address
$locale = User-Info -locale            # Return the user's locale, eg 'en_CA'
$userName = User-Info -userName        # Return the user's login name
$language = User-Info -language        # Return the user's language, eg 'en_US' or 'de'
$userType = User-Info -userType        # Return the user's type, eg 'Standard'
$timeZone = User-Info -timeZone        # Return the user's time zone, eg 'Asia/Tokyo'
$profileId = User-Info -profileId      # Return the user's profile ID
$userRoleId = User-Info -userRoleId    # Return the user's role IDTry
# Organization information
$id = Org-Info -id          # Return the organization ID
$name = Org-Info -name      # Return the organization name
$url = Org-Info -url        # Return the unique org URL, eg ''Try
# URL information
$text = Url-Info $url -host        # Return the host part of the URL
$text = Url-Info $url -path        # Return the path part of the URL
$text = Url-Info $url -port        # Return the port part of the URL
$text = Url-Info $url -protocol    # Return the protocol part of the URL
 $map = Url-Info $url -query       # Return the URL's query parameters as a mapTry


List commands

# Commands that transform the list:
$list = List-Apply   $list ${...}    # Apply the logic in ${...} to each item in the list
$list = List-Sort    $list ${...}    # Sort the list using the sort logic in ${...}
$list = List-Reverse $list           # Reverse the order of the list items
# Commands that return a new list:
$new = List-Copy     $list           # Return a deep copy of the list 
$new = List-Filter   $list ${...}    # Return items that meet the condition in ${...}
$new = List-Unique   $list           # Return the list after removing duplicate items
$new = List-First    $list $N        # Return the first (or first N) items of the list
$new = List-Last     $list $N        # Return the last (or last N) items of the list
$new = List-Union    $list $list2    # Return $list and $list2 combined into a single list
$new = List-Project  $list ${...}    # Return a new list transformed by the logic in ${...}
$map = List-ToMap    $list ${...}    # Return a map, keyed on the logic in ${...}
# Commands that aggregate a result:
$num = List-Sum $list ${...}      # Sum across each number retrieved by logic in ${...}
$num = List-Avg $list ${...}      # Average across each number retrieved by logic in ${...}
$num = List-Min $list ${...}      # Return the lowest number retrieved by logic in ${...}
$num = List-Max $list ${...}      # Return the highest number retrieved by logic in ${...}
$txt = List-Concat $list $delim   # Concatenate the list items into a single text value


Crypto commands

$b64 = Crypto-Encode $algo $key $cleartext $iv    # Encrypt cleartext with optional IV
$b64 = Crypto-Decode $algo $key $ciphertext $iv   # Decrypt ciphertext with optional IV
$b64 = Crypto-Generate-Key $size                  # Generates AES key of size
$b64 = Crypto-Generate-Digest $algo $data         # Compute one-way hash digest
$b64 = Crypto-Generate-Mac $algo $data $key       # Compute message auth code (MAC)
$b64 = Crypto-Sign $algo $input $keyOrCert        # Compute digital signature
$bool= Crypto-Verify $algo $data $sig $keyOrCert  # Verify a digital signature
$bool= Crypto-Verify-Hmac $algo $input $key $mac  # Verify with secure compare


Script commands

$bool = Script-IsTest           # Return true when running under test mode
 $int = Script-Epoch            # Return current time as milliseconds since 1970-01-01 GMT
 $num = Script-Random           # Return a positive number greater than 0.0 and less than 1.0
  $dt = Script-Now              # Return current datetime, eg '2022-12-24T23:59:59.999Z'
$date = Script-Today            # Return today's date referencing the current user time zone
$vars = Script-Flow $flow $vars # Run a flow interview with the given input variables
        Script-Abort $id        # Aborts the queueable job, batch job, or scheduled job
        Script-Log $message     # Write the specified message to the script log
        Script-Future $state ${...} # Execute logic in a @Future
 $any = Script-Call $class $method $args # Run an Apex class that implements Callable
 $map = Script-Invoke $type $action $params # Run any Invocable Action, including Apex
  $id = Script-Batch $size $data $state ${...} # Execute batch logic and return ID
  $id = Script-Enqueue $state ${...} -finalizer # Enqueue logic and return job ID
  $id = Script-Schedule $name $cron $state ${...} # Schedule logic and return ID







Text methods

$bool = $text.isBlank()           # Return true if the text is empty '' or null
 $int = $text.length()            # Return how many Unicode characters the text contains
$bool = $text.startsWith($prefix) # Return true if the text begins with the specified prefix
$bool = $text.contains($fragment) # Return true if the text contains the fragment
$bool = $text.endsWith($suffix)   # Return true if the text ends with the specified suffix
$list = $text.chars()             # Return the list of character codes representing the text
 $int = $text.charAt($index)      # Return the value of the character at the specified index
 $int = $text.find($fragment)     # Return the index of the first occurrence, or -1 otherwise
$text = $text.left($length)       # Return the leftmost characters for the specified length
$text = $text.mid($start, $len)   # Return the text from the start index to the length given
$text = $text.right($length)      # Return the rightmost characters for the specified length
$text = $text.replace($find, $re) # Replace each $find occurrence in $text with $replace
$list = $text.split($regexp)      # Return a list of text parts, split by regular expression*
$text = $text.substr($beg, $end)  # Return the part of text between the start and end index
$text = $text.lower()             # Return the text with all letters converted to lowercase
$text = $text.upper()             # Return the text with all letters converted to uppercase
$text = $text.trim()              # Return the text with no leading nor trailing white space
$text = $index.choice($labels)    # Return Nth label or argument, eg 'None', 'One', 'Many'


Number methods

$num = $num.abs()             # Return the absolute value of the number
$num = $num.pow($exp)         # Return the value of the number to the power of exponent
$num = $num.round()           # Return the rounded number using half-even rounding mode
$num = $num.mod($divisor)     # Return the remainder of the number divided by the divisor
$odd = $num.isOdd()           # Return true for odd numbers 1, 3, 5...


Boolean operators

$bool = $a == $b                # Equals
$bool = $a != $b                # Not equal
$bool = $a <  $b                # Less Than
$bool = $a <= $b                # Less than or equal to
$bool = $a >= $b                # Greater than or equal to
$bool = $a >  $b                # Greater than
$bool = $a in $list             # Is value in a list
$bool = $a notin $list          # Is value missing from a list
$bool = $a like $wildcard       # Like wildcard pattern*
$bool = $a notlike $wildcard    # Not like wildcard pattern
$bool = $a match $regexp        # Matches regular expression*
$bool = $a notmatch $regexp     # Not matches regular expression
$bool = $a and $b               # && Boolean AND
$bool = $a or $b                # || Boolean OR
$bool = not $a                  # ! Boolean NOT


Date methods

 $int = $date.year()             # Return the year part of the date
 $int = $date.month()            # Return the month part of the date, eg January = 1
 $int = $              # Return the day-of-month part of the date
$date = $date.addYears($years)   # Add the given number of years to the returned date
$date = $date.addMonths($months) # Add the given number of months to the returned date
$date = $date.addDays($days)     # Add the given number of days to the returned date


Datetime methods

 $int = $dt.epoch()              # Return datetime as milliseconds since 1970-01-01 GMT
$date = $$gmt)           # Return date in the user time zone (or GMT if arg is true)
$time = $dt.time($gmt)           # Return time in the user time zone (or GMT if arg is true)
 $int = $dt.dayOfWeek($gmt)      # Return the weekday, eg Monday = 1, Tuesday = 2, etc
$text = $dt.format($format, $tz) # Format datetime using a specific format* and time zone


Time methods

 $int = $time.hour()               # Return the hour part of the time
 $int = $time.minute()             # Return the minute part of the time
 $int = $time.second()             # Return the second part of the time
 $int = $time.millis()             # Return the millisecond part of the time
$time = $time.addHours($hours)     # Add the number of hours to the returned time
$time = $time.addMinutes($minutes) # Add the number of minutes to the returned time
$time = $time.addSeconds($seconds) # Add the number of seconds to the returned time
$time = $time.addMillis($millis)   # Add the number of milliseconds to the returned time


Type convert methods

  $id = $id.to18()             # Convert the ID to 18 characters
  $id = $id.to15()             # Convert the ID to 15 characters
$text = $var.toText()          # Convert the variable to a Text value
 $num = $var.toNumber()        # Convert the variable to a Number value
$bool = $var.toBoolean()       # Convert the variable to a Boolean value
$name = $id.idType()           # Return the SObject API name for the ID
$type = $var.type()            # Return type as null, 'Text', 'Number', 'Boolean', 'List', 'Map'


Map methods

 $get = $map.get($key)         # Get a value from a map dynamically
 $put = $map.put($key, $val)   # Set a value on the map and return the new value
 $map = $map.clear()           # Remove all the keys and values from the map
$copy = $map.clone()           # Return a shallow copy of the map
$bool = $map.hasKey($key)      # Return true if map contains specified key
$bool = $map.isEmpty()         # Return true if map contains no keys and no values
$keys = $map.keys()            # Return a list containing all the keys in the map
 $map = $map.putAll($source)   # Copy all keys and values of the source map into the map
 $val = $map.delete($key)      # Delete the map key and return its value
$text = $map.toUrl()           # Return a URL query string from a map of query parameters
$vals = $map.values()          # Return a list containing all values in the map


List methods

$list = $list.add($item)        # Add the item to the end of the list
$list = $list.addAll($items)    # Add all the items to the end of the list
$list = $list.clear()           # Remove all items from the list
$copy = $list.clone()           # Return a shallow copy of the list
$bool = $list.hasItem($item)    # Return true if the list contains the item
 $num = $list.indexOf($item)    # Return the index of the first occurrence of the item
$bool = $list.isEmpty()         # Return true if list the has zero items
$text = $list.join($separator)  # Join the list items into a single text value
$item = $list.remove($index)    # Removes the item at the index and returns it
 $num = $list.size()            # Return the number of items in the list
$list = $list.sort()            # Sort the items in the list 







Examples of maps and lists

Maps associate one or more key-value pairs. A record is an example of a map having many keys (record fields) and associated values. Each value is stored or retrieved using its key. All map keys are text, and map values may consist of any type including another map.

# an empty map
$map = { }

# a map of currency symbol to exchange rate
$gbp_rates = { USD: 1.22, EUR: 1.16, JPY: 167.42 }

# store and retrieve map values
$gbp_rates.CAD = 1.65
$rate = $gbp_rates.CAD

# a map of airline code to airline name
$codename = { AA: 'American Airlines' }

# put() the key in quotes if it contains numbers or special characters
$codename.put('5Y', 'Atlas Air')
$codename.put('?', 'Unknown Airline')

Lists are a collection of items. Items in a list may consist of any type including another list. Use the dot . operator to refer to any item by its index. Unlike a map, items in a list are ordered.

# an empty list
$list = [ ]

# fill a list using a range
$letters = 'a'..'z'
$daysInJanuary = 1..31

# sort a list of prices
$prices = [ 3.50, 1.00, 9.99 ]

# get the first, second, third item in a price list
$cheapest = $prices.0      # the index 0 is the 1st in the list
$midprice = $prices.1      # the index 1 is the 2nd in the list
$expensive = $prices.2     # the index 2 is the 3rd in the list

# negative index counts from the end of the list 
$expensive = $prices.-1    # the index -1 gets the last item
$expensive = $prices.get($prices.size - 1) # also gets the last item

Combine lists and maps to model table rows and columns.

# map of prices
$plans =
    BASIC: 9.00
    PREMIUM: 12.50
    ENTERPRISE: 20.00

# list of account records
$accounts =
    { Name: 'Dickenson Plc',          Code: 'A010',    Plan: 'BASIC' }
    { Name: 'GenePoint',              Code: 'A013',    Plan: 'PREMIUM' }
    { Name: 'Grand Hotels',           Code: 'A024',    Plan: 'ENTERPRISE' }
    { Name: 'Wide World importers',   Code: 'A033',    Plan: 'PREMIUM' }

# a list inside a list represents a table
$expectedAnnualRevenues =
    [ $accounts.0.Code, $accounts.0.Plan, $plans.get($accounts.0.Plan) * 12 ]
    [ $accounts.1.Code, $accounts.1.Plan, $plans.get($accounts.1.Plan) * 12 ]
    [ $accounts.2.Code, $accounts.2.Plan, $plans.get($accounts.2.Plan) * 12 ]
    [ $accounts.3.Code, $accounts.3.Plan, $plans.get($accounts.3.Plan) * 12 ]



Parameters change a command's behavior. For example, the Http-Post command is affected by its URL, headers, and body. Parameters can be specified by name, or by order.

# Specify each parameter name followed by its value
Http-Post -url '' -headers {Cookie:null} -body 'data'

# Alternatively, specify just the values (in the correct order)
Http-Post '' {Cookie:null} 'data'

Flags are parameters that have no value. The presence (or not) of a flag affects the command. For example Datetime has a -GMT flag. Flag parameters may appear in any order.

# one second before Christmas in GMT time zone
Datetime-Value 2022 12 24 23 59 59 -gmt

# one second before Christmas, user time zone
Datetime-Value 2022 12 24 23 59 59

Aliases are shortcuts to a command that can make logic less verbose. The alias reduces a command to one word and does not affect its behavior.

# one second before Christmas, user time
Datetime 2022 12 24 23 59 59







Logic blocks

A logic block ${...} is a mini procedure that alters how a command runs. For example:


Here is a logic block ${...} appearing as a parameter on the Enqueue command:


Logic blocks are similar to JavaScript lambdas or arrow functions and come in two forms.

# Block form
Enqueue ${
    Http-Post '' # async callout
Try# Concise form
$sunday = 1 # where booking date falls on a sunday
$dates = [ '2022-12-10', '2022-12-11', '2022-12-12' ]
$sundays = Filter $dates $_.dayOfWeek.eq($sunday) # concise logic omits the curly braces


Logic blocks can make business logic more readable. Meaningful comments and variable names help too. These two examples produce the same result but in different ways:

Try# Logic block - find odd numbers
$odds = Filter [1, 2, 3, 4, 5] $_.isOdd
Try# Foreach Loop - find odd numbers (same result)
$odds = []
foreach ($item in [1, 2, 3, 4, 5]) {
    if ($item.isOdd) {


Like an anonymous callback, commands may accept values for use inside the logic.

Try# Required values - each item availed to logic
$values = [1, 2, 3, 4, 5]
$odds = Filter $values $_.isOdd
# Optional value - availed to logic
Enqueue $value ${
    Http-Post '' -body $_


Advanced example - sort a list of nested maps
This specifies a primary order and secondary order using the special $_ variable twice:

$list_applications = [
   { Course: 'Postgrad',  Student: {Score: 80, Name: 'Tom'} }
   { Course: 'Undergrad', Student: {Score: 60, Name: 'Liz'} }
   { Course: 'Postgrad',  Student: {Score: 70, Name: 'Jim'} }
   { Course: 'Undergrad', Student: {Score: 90, Name: 'Bob'} }

# Sort by course then by score (note the concise logic)
$by_course_score = Sort $list_applications [ $_.Course, $_.Student.Score ]

Result: [
    { Course: 'Postgrad',   Student: {Score: 70, Name: 'Jim'} }
    { Course: 'Postgrad',   Student: {Score: 80, Name: 'Tom'} }
    { Course: 'Undergrad',   Student: {Score: 60, Name: 'Liz'} }
    { Course: 'Undergrad',   Student: {Score: 90, Name: 'Bob'} }



Pipes are commands chained together using the pipe | operator. Pipes feed the data from the left of the pipe | operator into the command on the right. When the data is a list, the command acts on each item one by one. Use pipes to transform and combine lists and maps.

Try# european taxes
$eu_taxes = [
20, 21, 20, 19, 21, 19, 25, 20, 24,
21, 24, 20, 25, 27, 23, 22, 21, 17,
21, 18, 21, 23, 23, 19, 25, 22, 20]

# the top three european taxes are 27%, 25%, 24%
$top_taxes = $eu_taxes | Unique | Sort | Reverse | Top 3

Special $_ variable refers to the current value being worked on.

Here is another example with logic blocks, the special variable, pipes and commands. Each list item feeds into the command after a pipe. $_ is the current item being worked on.

# Debit lines used to create an accounting journal
$debits = [
    {Code: 'Rent', Amount: 8800}
    {Code: 'Heat', Amount: 1100}

# Pipe Approach - create journal
$credits = $debits
         | Copy
         | Apply ${ $_.Amount *= -1 }
         | Apply ${ $_.Code = 'Bank'}
$journal = $credits + $debits

# Loop Approach - create journal (same result)
$journal = []
foreach ($debit in $debits)
    $credit = $debit.clone()
    $credit.Amount *= -1
    $credit.Code = 'Bank'

# net balance
$balance = Sum $journal $_.Amount
Log $balance # zero



Functions are blocks of re-usable logic. For example, a function can be written to retrieve one exchange rate, then it can be generalized and re-used to retrieve different rates.

Use parentheses after the function name to define comma separated parameters. Use return to hand back the function results. Think of a function as your own custom command.

Tryfunction Calculate-Age($birthdate)
    $today = Script-Today
    return $today.year - $birthdate.year

# use the function as you would use a command  
$age = Calculate-Age '1991-02-17'
Log `Edward Sheeran is $age years old`


Handling errors

Errors happen when you try something bad, like dividing by zero. If that happens, catch the error and supply logic to report it, or choose to do something else instead.

Put your happy path logic in a try block, and your error handling logic in a catch block. If an error occurs, the special $_ variable holds the error detail. This is known as an exception.

    $discount = ($listPrice - $salePrice) / $listPrice
    throw `Cannot calculate discount: $_`

Optionally, the throw keyword allows you to raise your own error with your own message.


Binary data

Streamscript supports the use of binary data. To use binary data in HTTP requests and HTTP responses, use the -base64 flag when running HTTP commands. This flag treats both the request and response body as base64 encoded binary data.

In this example, a PDF invoice is retrieved. The PDF body is stored on the Document Body field as-is, because it was already encoded by the HTTP command using the -base64 flag. Return the $Document record so that Flow Builder can insert it.

# get pdf invoice, base64 encoded
$url = ''
$pdf = Http-Get $url -base64

# new record
$Document = New-Document {
    Name = 'inv.pdf'
    Body = $pdf.body

# output as SObject
return $DocumentTry

Alternatively you can store and retrieve plain text in blob fields like Document Body, so long as the Base64-Encode command is used to encode the stored text, or use Base64-Decode to retrieve a binary field back as text.


Bulk/mass actions and directives

Directives must occupy the first line of the script in the form of a comment, for example:

In bulk mode your script will be executed exactly once even though there may be more than one initiating request. For this reason, you must treat merge fields as lists, and you must return a corresponding list. Example:

# Streamscript Bulk
$accounts = {!$Record}
$size = $accounts.size()

# retrieve many cat facts in one callout
$http = Http-Get `$size`
$result = Json-Decode $http.body
$facts = $

# put each cat fact on each account
for ($i = 0; $i < $size; $i++)
    # use the same list index
    $fact = $facts.get($i)
    $acct = $accounts.get($i)
    $acct.Description = `$fact`

When making callouts, we recommend:
- Enable Lightning runtime for flows: Setup > Process Automation Settings
- For screen flows, check: Always start a new transaction (on the step, under advanced)
- For record-triggered flows, check: Run Asynchronously path to access an external system
   after the original transaction for the triggering record is successfully committed.



Webhooks are flows that are triggered in response to web requests, as opposed to record changes. With a webhook, data is received from an external application at a site belonging to your Salesforce instance. When events arrive at your URL, the associated flow is triggered with access to the data sent from the external system.

Follow the site setup video then visit the Integrations tab to handle webhooks:

Read the request data from the $Webhook request properties:

Try$Webhook.request           # Request body
$Webhook.requestIp         # IP address
$Webhook.requestUri        # Resource URI
$Webhook.requestPath       # Path starting with /
$Webhook.requestMethod     # HTTP request method
$Webhook.requestParams     # Map of URL parameters
$Webhook.requestHeaders    # Map of HTTP request headers

Write the response data to the $Webhook response properties:

$Webhook.response           # Response body
$Webhook.responseStatus     # HTTP status code
$Webhook.responseHeaders    # Map of HTTP response headers

Don't overwrite the $Webhook.responseHeaders variable. Add values to the map like this:
$Webhook.responseHeaders.Content-Type = 'text/xml'







Appendix - Date/Time Formats

Dates and times always use ISO-8601. To display any other format, use the format() method.

# ISO-8601
$date = '2022-12-24'
$time = '23:59:59.999Z'
$datetime = '2022-12-24T23:59:59.999Z'
$ddMMyyyy = $datetime.format('dd/MM/yyyy') # 24/12/2022
Example Format Example Result
"yyyy.MM.dd G 'at' HH:mm:ss z" 2001.07.04 AD at 12:08:56 PDT
"EEE, MMM d, ''yy" Wed, Jul 4, '01
"h:mm a" 12:08 PM
"hh 'o''clock' a, zzzz" 12 o'clock PM, Pacific Daylight Time
"K:mm a, z" 0:08 PM, PDT
"yyyyy.MMMMM.dd GGG hh:mm aaa" 2001.July.04 AD 12:08 PM
"EEE, d MMM yyyy HH:mm:ss Z" Wed, 4 Jul 2001 12:08:56 -0700
"yyMMddHHmmssZ" 010704120856-0700
"yyyy-MM-dd'T'HH:mm:ss.SSSZ" 2001-07-03T12:08:56.235-0700
"yyyy-MM-dd'T'HH:mm:ss.SSSXXX" 2001-07-03T12:08:56.235-07:00
"YYYY-'W'ww-u" 2001-W27-3
Letter Component Presentation Examples
G Era designator Text AD
y Year Year 1996; 96
Y Week year Year 2009; 09
M Month in year Month July; Jul; 07
w Week in year Number 27
W Week in month Number 2
D Day in year Number 189
d Day in month Number 10
F Day of week in month Number 2
E Day name in week Text Tuesday; Tue
u Day number (1 = Monday, 7 = Sunday) Number 1
a Am/pm marker Text PM
H Hour in day (0-23) Number 0
k Hour in day (1-24) Number 24
K Hour in am/pm (0-11) Number 0
h Hour in am/pm (1-12) Number 12
m Minute in hour Number 30
s Second in minute Number 55
S Millisecond Number 978
z Time zone General time zone Pacific Standard Time; PST; GMT-08:00
Z Time zone RFC 822 time zone -0800
X Time zone ISO 8601 time zone -08; -0800; -08:00


Appendix - Regular Expressions

Streamscript uses regular expressions to split and match.

# does a text value match the phone number format
'408-971-2288' match '^\b\d{3}[-.]?\d{3}[-.]?\d{4}\b$'       # true
# extract text items separated by numbers
'aaa123bbb456ccc789'.split('\d+')                            # ["aaa","bbb","ccc"]
Regex Basics Description
^ The start of a string
$ The end of a string
. Wildcard which matches any character, except newline (\n).
| Matches specific character(s) on either side, eg a|b corresponds to a or b
\ Used to escape a special character
a The character "a"
ab The string "ab"
Quantifiers Description
* Used to match 0 or more of the previous (e.g. xy*z could correspond to "xz", "xyz" etc.)
? Matches 0 or 1 of the previous
+ Matches 1 or more of the previous
{5} Matches exactly 5
{5, 10} Matches everything between 5-10
Character Description
\s Matches a whitespace character
\S Matches a non-whitespace character
\w Matches a word character
\W Matches a non-word character
\d Matches one digit
\D Matches one non-digit
[\b] A backspace character
\c A control character
Special Description
\n Matches a newline
\t Matches a tab
\r Matches a carriage return
\ZZZ Matches octal character ZZZ
\xZZ Matches hex character ZZ
\0 A null character
\v A vertical tab
Groups Description
(xyz) Grouping of characters
(?:xyz) Non-capturing group of characters
[xyz] Matches a range of characters (e.g. x or y or z)
[^xyz] Matches a character other than x or y or z
[a-q] Matches a character from within a specified range
[0-7] Matches a digit from within a specified range


Appendix - Wildcard Patterns

Use a template containing wildcard and the like or notlike method to match text

'1234'.like('_23_')    # true
Wildcard Description
_ a placeholder representing any character 
% a placeholder representing any character, any number of times


Appendix - Operators

Boolean Operators Description
 == Equals
 != Not equal
Less Than 
 <= Less than or equal to
 >= Greater than or equal to
 >  Greater than 
 in Is value in a list
 notin Is value missing from a list
 like Like wildcard pattern
 notlike Not like wildcard pattern 
 match Matches regular expression
 notmatch Not matches regular expression 
 && Boolean AND 
 || Boolean OR
 ! Boolean NOT 
Math Operators Description
.. Range
= Assignment
* Multiplier
^ Power
/ Division
% Modulus
+ Addition
- Subtraction
*= Multiply then assign
/= Division then assign
%= Remainder then assign
+= Addition then assign
-= Subtraction then assign
Other Operators Description
++ Increment
-- Decrement
| Pipe
? : Ternary


Appendix - Global Variables

Global variables may be used in a script via Merge Field syntax.

$Account = {!$Record} # map
Record Resources Data Type
$Record SObject
$Record__Prior SObject
Flow Resources      
$Flow.CurrentDate Date $Flow.InterviewStartTime DateTime
$Flow.CurrentDateTime DateTime $Flow.ActiveStages String
$Flow.FaultMessage String $Flow.InterviewGuid String
$Flow.CurrentStage String $Flow.CurrentRecord String
Organization Resources      
$Organization.City String $Organization.Longitude Number
$Organization.Country String $Organization.Name String
$Organization.Division String $Organization.Phone String
$Organization.Fax String $Organization.PostalCode String
$Organization.GeocodeAccuracy String $Organization.State String
$Organization.Id String $Organization.Street String
$Organization.Latitude Number $Organization.UiSkin String
Profile Resources      
$Profile.LastModifiedDate DateTime $Profile.CreatedById String
$Profile.ManageUsers Boolean $Profile.CreatedDate DateTime
$Profile.Name String $Profile.Description String
$Profile.UsageType String $Profile.Id String
$Profile.UserType String $Profile.LastModifiedById String
User Resources      
$User.Alias String $User.Latitude Number
$User.City String $User.LocaleSidKey String
$User.CommunityNickname String $User.Longitude Number
$User.CompanyName String $User.ManagerId String
$User.ContactId String $User.MobilePhone String
$User.Country String $User.Phone String
$User.Department String $User.PostalCode String
$User.Email String $User.ProfileId String
$User.EmployeeNumber String $User.Signature String
$User.EndDay String $User.StartDay String
$User.Extension String $User.State String
$User.Fax String $User.Street String
$User.FederationIdentifier String $User.TimeZoneSidKey String
$User.FirstName String $User.Title String
$User.GeocodeAccuracy String $User.UITheme String
$User.Id String $User.UIThemeDisplayed String
$User.IsActive Boolean $User.Username String
$User.LanguageLocaleKey String $User.UserRoleId String
$User.LastName String $User.UserType String
User Role Resources      
$UserRole.CaseAccessForAccountOwner String $UserRole.MayForecastManagerShare Boolean
$UserRole.ContactAccessForAccountOwner String $UserRole.Name String
$UserRole.DeveloperName String $UserRole.OpportunityAccessForAccountOwner String
$UserRole.Id String $UserRole.PortalRole String
$UserRole.LastModifiedById String $UserRole.PortalType String
$UserRole.LastModifiedDate DateTime $UserRole.RollupDescription String


Getting started with Streamscript
Install from the Salesforce AppExchange
Package install link: /packaging/installPackage.apexp?p0=04tGA000005ZGcU