Webhooks in
Salesforce Flow

Streamscript takes Flow to new territory.
Receive webhooks and make API callouts
with straightforward, formula-based actions.

Get Started


Trusted by Salesforce's most innovative customers




Streamscript runs exclusively on Salesforce - no data passes through any other server.


Bring CSV, XML, JSON capabilities (webhooks and more) directly into flow using Streamscript, and benefit from flow security settings, flow versioning and flow tests.



Get started

You can replicate this in your own org:

  1. Install the Streams package in Sandbox or Production (direct URL)
  2. Go to Setup > Flows > New Autolaunched Flow
  3. Add an action element, type: Streamscript
  4. Copy and paste the above exchange rate example into your step
  5. Save the flow, then click debug.

That's it! You just integrated live exchange rates into your flow.




Show more videos...



Show more tutorials...



Show more recipes...


Q & A


Q: Where is the package?
Here is the install URL: /packaging/installPackage.apexp?p0=04tGA000005BsIL

Q: What is inside the package?
The package contains: 1 custom object, 5 apex classes, and 1 LWC for the script editor.

Q: Is the package security reviewed?
Yes. Latest details here. Streams is published on the AppExchange with Aloha status from Salesforce. At install you can click 'View Components' to verify it contains no integrations.

Q: Is this related to OmniScript, Mule DataWeave scripts, or AMPscript?
No. Those environments are separate from flow. Streamscript runs in native Salesforce flows.



Q: How do I get syntax highlighting and autocompletions?
We use this optional Chrome Extension or Firefox Add-on in our videos.
Follow the extension install steps. Our playground also provides highlighting.

Q: Does it support bulkification?
Yes. Best practice for record-triggered flows is to use the Bulk directive. In bulk mode, Streamscript will run once instead of many times. Inputs or merge fields will contain lists instead of a single value. Outputs or return values will expect lists instead of a single value.

Q: How do I make an API call from a Record-Triggered Flow?
Salesforce supports HTTP from record triggers, but the script must be asynchronous. Move the callout logic from "Run Immediately" to the "Run Asynchronously" path. This will resolve errors such as "You have uncommitted work pending. Please commit or rollback before calling out". Use the Bulk directive to transmit up to 200 records in each request.

Q: How do I set response headers on my inbound webhook?
Use the variable $Webhook.responseHeaders to set response headers. Without overwriting the map, add values like this: $Webhook.responseHeaders.Content-Type = 'text/xml'

Q: How can I send auth headers in my HTTP callout?
Set up a Named Credential then use as follows: Http-Post 'callout:My_Cred/path/to/api'
Avoid handling session ids, usernames, passwords or authentication tokens within your logic. If you use External Credentials, set the Managed Package Access: Streams

Q: Why is %7B%21%24 appearing in my named credential or external credential?
You URL encoded the {!$Credential.Password} or used toUrl on it. Take care to separate the credential from other params, then append it to the request body to preserve it unencoded.

Q: How to convert a UNIX epoch timestamp (in seconds) into a datetime?
Add the timestamp to 1970-01-01 like this: $dt = Datetime 1970 1 1 0 0 $timestamp -gmt
Or like this, for timestamps in milliseconds: $dt = Datetime 1970 1 1 0 0 0 $millis -gmt

Q: Can I access all of the fields on my records?
Streamscript supports all fields on all objects, including standard, custom, managed, platform events, and custom metadata, wherever the running user has CRUD and FLS permissions.

Q: How do I send URL encoded form data in an HTTP post?
Prepare a map of parameters, then use toUrl which converts it to text in key=val format:

# Post form data
$url = 'httpbin.org/post'
$body = {id: '123', type: 'order'}.toUrl()
$headers = {Content-Type: 'application/x-www-form-urlencoded'}
return Http-Post $url $headers $bodyTry

Q: How can my Webhook receive URL encoded form data posted to it?
Read map values off $Webhook.requestParams (the $Webhook.request body will be blank)

# Webhook
return New-Case {
    Subject = $Webhook.requestParams.issueId,
    Description = $Webhook.requestParams.issueSummary

Q: How do I get nested or parent record attributes in a Record Triggered Flow?
Use a query, or create formulas so that the related fields are availed on the record:

# Streamscript to get parent record attributes
$Contact = Query-Record 'SELECT Account.Owner.Name FROM Contact LIMIT 1'
return $Contact.Account.Owner.NameTry

Q: How do I access the results of script in subsequent steps?
One-line scripts automatically return the result of the expression. Streamscript will set the output variable (num, bool, text, list, record, records) according to the result data type.
Multi-line scripts use the return keyword. For example: return $num or return $list
When returning SObjects, the variable name must be the type, eg: return $Invoice__c
Note flow API names are case sensitive: $name__c $Name__c $Name__C are different.




- Record-Upsert supports -system parameter to perform DML in System Context.
- Parameterised return fix, permits upstream logic blocks in same script.
- Query commands support SOQL :bindings using any $variable name.
- Script-Batch command, supports List data and QueryLocator data.
- Record-Upsert fix, supports non-reparentable master-detail fields.
- Logic blocks support Function calls in async commands (used for chaining).
- Record commands support FlowPicklistValue fields from Transform elements.
- Script-Future supports HTTP callouts in the logic block.

- CSV Encode and Decode commands.
- Script-Enqueue supports -finalizer parameter and $__.finalizer special variable.
- Json-Decode advisory message: 'Decode not needed, value is already in map form'.
- Datetime-Value integer overflow fix to support millisecond Unix Epoch timestamp conversion.

- Bulk directive relaxes validation if script returns HTTP value.
- HTTP commands support null response bodies for binary requests.
- Record-Insert and Record-Update support -system parameter to offload System Mode DML.

- HTTP commands support -timeout parameter.
- Script-Enqueue supports Job ID via $__.id special variable.
- Http-Delete command supports nonstandard -body parameter.
- Unary minus operator supports expressions like $credit = -$debit.

- Hex-Encode and Hex-Decode commands.
- Recurring decimal fix for overscale formula fields eg 11.11111111111111
- Crypto commands for encode, decode, MAC generation, signing and HMAC verification.

- Lead object fix to support Last Transfer Date field.
- Business Hours commands accept either Name or ID.


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