-
Notifications
You must be signed in to change notification settings - Fork 0
Constructs
So far, we have introduced all the parts of the language that allow us to extract data from an input JSON document, combine the data using string and numeric operators, and format the structure of the output JSON document. What follows are the parts that turn this into a Turing-complete, functional programming language.
JSONata expressions can be interleaved with comments using 'C' style comment delimiters. For example:
/* Long-winded expressions might need some explanation */
(
$pi := 3.1415926535897932384626;
/* JSONata is not known for its graphics support! */
$plot := function($x) {(
$floor := $string ~> $substringBefore(?, '.') ~> $number;
$index := $floor(($x + 1) * 20 + 0.5);
$join([0..$index].('.')) & 'O' & $join([$index..40].('.'))
)};
/* Factorial is the product of the integers 1..n */
$product := function($a, $b) { $a * $b };
$factorial := function($n) { $n = 0 ? 1 : $reduce([1..$n], $product) };
$sin := function($x){ /* define sine in terms of cosine */
$cos($x - $pi/2)
};
$cos := function($x){ /* Derive cosine by expanding Maclaurin series */
$x > $pi ? $cos($x - 2 * $pi) : $x < -$pi ? $cos($x + 2 * $pi) :
$sum([0..12].($power(-1, $) * $power($x, 2*$) / $factorial(2*$)))
};
[0..24].$sin($*$pi/12).$plot($)
)
If/then/else constructs can be written using the ternary operator ? :.
predicate ? expr1 : expr2
The expression predicate is evaluated. If its effective Boolean value is true, then expr1 is evaluated and returned, otherwise expr2 is evaluated and returned.
Example
Account.Order.Product.{
`Product Name`: $.Price > 100 ? "Premium" : "Basic"
}
The default (or "elvis") operator is syntactic sugar for a common pattern using the ternary operator. It returns the left-hand side if it has an effective Boolean value of true, otherwise it returns the right-hand side.
expr1 ?: expr2
This is equivalent to expr1 ? expr1 : expr2. The elvis operator is useful for providing fallback values when an expression may evaluate to a value with an effective Boolean value of false, without having to repeat the expression twice as you would with the ternary operator.
Example
Account.Order.Product.{
`Product Name`: $.'Product Name',
`Category`: $.Category ?: "Uncategorized"
}
The coalescing operator is syntactic sugar for a common pattern using the ternary operator with the $exists function. It returns the left-hand side if it is defined (not undefined), otherwise it returns the right-hand side.
expr1 ?? expr2
This is equivalent to $exists(expr1) ? expr1 : expr2. The coalescing operator is useful for providing fallback values only when the left-hand side is missing or not present (empty sequence), but not for other values with an effective Boolean value of false like 0, false, or ''. It avoids having to evaluate the expression twice and explicitly use the $exists function as you would with the ternary operator.
Example
Account.Order.{
"OrderID": OrderID,
"Rating": ($sum(Product.Rating) / $count(Product.Rating)) ?? 0
}
Any name that starts with a dollar $ is a variable. A variable is a named reference to a value. The value can be one of any type in the language's type system.
-
$— The variable with no name refers to the context value at any point in the input JSON hierarchy. -
$$— The root of the input JSON. Only needed if you need to break out of the current context to temporarily navigate down a different path, e.g. for cross-referencing or joining data. - Native (built-in) functions — see the function library.
Values (of any type in the type system) can be bound to variables:
$var_name := "value"
The stored value can be later referenced using the expression $var_name. The scope of a variable is limited to the 'block' in which it was bound. For example:
Invoice.(
$p := Product.Price;
$q := Product.Quantity;
$p * $q
)
This returns Price multiplied by Quantity for the Product in the Invoice.
The function is a first-class type, and can be stored in a variable just like any other data type. A library of built-in functions is provided and assigned to variables in the global scope. For example, $uppercase contains a function which, when invoked with a string argument str, returns a string with all the characters in str changed to uppercase.
A function is invoked by following its reference (or definition) by parentheses containing a comma-delimited sequence of arguments.
Examples
-
$uppercase("Hello")returns the string"HELLO". -
$substring("hello world", 0, 5)returns the string"hello". -
$sum([1,2,3])returns the number6.
Anonymous (lambda) functions can be defined using the following syntax:
function($l, $w, $h){ $l * $w * $h }
and can be invoked using:
function($l, $w, $h){ $l * $w * $h }(10, 10, 5)
which returns 500. The function can also be assigned to a variable for future use (within the block):
(
$volume := function($l, $w, $h){ $l * $w * $h };
$volume(10, 10, 5);
)
Functions can be defined with an optional signature which specifies the parameter types of the function. If supplied, the evaluation engine will validate the arguments passed to the function before it is invoked. A dynamic error is thrown if the argument list does not match the signature.
A function signature is a string of the form <params:return>. params is a sequence of type symbols, each one representing an input argument's type. return is a single type symbol representing the return value type.
Type symbols work as follows.
Simple types:
-
b— Boolean -
n— number -
s— string -
l—null
Complex types:
-
a— array -
o— object -
f— function
Union types:
-
(sao)— string, array or object -
(o)— same aso -
u— equivalent to(bnsl), i.e. Boolean, number, string ornull -
j— any JSON type. Equivalent to(bnsloa), i.e. Boolean, number, string,null, object or array, but not function -
x— any type. Equivalent to(bnsloaf)
Parametrised types:
-
a<s>— array of strings -
a<x>— array of values of any type
Some examples of signatures of built-in JSONata functions:
-
$counthas signature<a:n>; it accepts an array and returns a number. -
$appendhas signature<aa:a>; it accepts two arrays and returns an array. -
$sumhas signature<a<n>:n>; it accepts an array of numbers and returns a number. -
$reducehas signature<fa<j>:j>; it accepts a reducer functionfand ana<j>(array of JSON objects) and returns a JSON object.
Each type symbol may also have options applied:
-
+— one or more arguments of this type. E.g.$ziphas signature<a+>; it accepts one array, or two arrays, or three arrays, and so on. -
?— optional argument. E.g.$joinhas signature<a<s>s?:s>; it accepts an array of strings and an optional joiner string which defaults to the empty string. It returns a string. -
-— if this argument is missing, use the context value ("focus"). E.g.$lengthhas signature<s-:n>; it can be called as$length(OrderID)(one argument) but equivalently asOrderID.$length().
Functions that have been assigned to variables can invoke themselves using that variable reference. This allows recursive functions to be defined. For example:
(
$factorial := function($x){ $x <= 1 ? 1 : $x * $factorial($x-1) };
$factorial(4)
)
returns 24. Note that it is actually possible to write a recursive function using purely anonymous functions (i.e. nothing gets assigned to variables) using the Y-combinator.
A recursive function adds a new frame to the call stack each time it invokes itself. This can eventually lead to stack exhaustion if the function recurses beyond a certain limit. Consider the classic recursive implementation of the factorial function:
(
$factorial := function($x) {
$x <= 1 ? 1 : $x * $factorial($x-1)
};
$factorial(170)
)
This function works by pushing the number onto the stack, then, when the stack unwinds, multiplying it by the result of the factorial of the number minus one. Written in this way, the JSONata evaluator has no choice but to use the call stack to store the intermediate results. Given a large enough number, the call stack will overflow.
This is a recognised problem with functional programming, and the solution is to rewrite the function slightly to avoid the need for the stack to store the intermediate result. The following implementation of factorial achieves this:
(
$factorial := function($x){(
$iter := function($x, $acc) {
$x <= 1 ? $acc : $iter($x - 1, $x * $acc)
};
$iter($x, 1)
)};
$factorial(170)
)
Here, the multiplication is done before the function invokes itself, and the intermediate result is carried in the second parameter $acc (accumulator). The invocation of itself is the last thing that the function does. This is known as a 'tail call', and when the JSONata parser spots this, it internally rewrites the recursion as a simple loop. Thus it can run indefinitely without growing the call stack. Functions written in this way are said to be tail recursive.
A function, being a first-class data type, can be passed as a parameter to another function, or returned from a function. Functions that process other functions are known as higher order functions. Consider the following example:
(
$twice := function($f) { function($x){ $f($f($x)) } };
$add3 := function($y){ $y + 3 };
$add6 := $twice($add3);
$add6(7)
)
The function stored in variable $twice is a higher order function. It takes a parameter $f which is a function, and returns a function which takes a parameter $x which, when invoked, applies the function $f twice to $x. $add3 stores a function that adds 3 to its argument. Neither $twice nor $add3 have been invoked yet. $twice is invoked by passing the function $add3 as its argument. This returns a function that applies $add3 twice to its argument. This returned function is not invoked yet, but rather assigned to the variable $add6. Finally, the function in $add6 is invoked with the argument 7, resulting in 3 being added to it twice. It returns 13.
When a lambda function is defined, the evaluation engine takes a snapshot of the environment and stores it with the function body definition. The environment comprises the context item (i.e. the current value in the location path) together with the current in-scope variable bindings. When the lambda function is later invoked, it is done so in that stored environment rather than the current environment at invocation time. This property is known as lexical scoping and is a fundamental property of closures.
Consider the following example:
Account.(
$AccName := function() { $.'Account Name' };
Order[OrderID = 'order104'].Product.{
'Account': $AccName(),
'SKU-' & $string(ProductID): $.'Product Name'
}
)
When the function is created, the context item (referred to by $) is the value of Account. Later, when the function is invoked, the context item has moved down the structure to the value of each Product item. However, the function body is invoked in the environment that was stored when it was defined, so its context item is the value of Account. The expression produces the following result:
{
"Account": "Firefly",
"SKU-858383": "Bowler Hat",
"SKU-345664": "Cloak"
}Functions can be partially applied by invoking the function with one or more (but not all) arguments replaced by a question mark ? placeholder. The result of this is another function whose arity (number of parameters) is reduced by the number of arguments supplied to the original function. This returned function can be treated like any other newly defined function — e.g. bound to a variable, passed to a higher-order function, and so on. For example, you can create a function to return the first five characters of a string by partially applying the $substring function.
Source: support.fuuz.com
Getting Started (14)
- Access Field Level Help within the Fuuz Platform
- Field-Level Help
- Fuuz Platform 101: Low/No-Code Technology in Manufacturing
- Fuuz Platform Architecture
- Getting to Know the Fuuz Platform
- Logging into Fuuz – Cloud Access
- Manage what displays in Field Level Help throughout Fuuz
- Recovering Your Fuuz Account
- Sharing A Page
- Switching Between Apps in Fuuz
- Switching between Fuuz Environments (Build, QA, Production)
- Trouble Logging Into Fuuz
- Unique Email Plus Addressing
- Welcome To Industry Accelerators!
Training Guides (52)
Applications
- Brand and Configure Your Application
- Create an Application
- Deactivate (Retire) an Application
- Find Pages Beyond the Left Menu
- Install a Fuuz Package
- Navigate the Application Designer
- Retire an Application
Access & Users
- Approve Access Requests
- Approve Application Access Requests
- Configure the Internal Password Policy
- Create a Role
- Create an API Key
- Deactivate and Reactivate a User
- Grant Permissions with Policies
- Investigate Login Activity
- Invite a User to an Application
- Manage App Users
- Request Access to an Application
- Switch Applications, Roles, and Environments
- Understand Developer Access
- Understand Web Access
- Use the User Menu (Profile, Theme, and More)
Data Models & Schema
- Add a Custom Field
- Create a Data Model
- Create a Sequence
- Design Model Fields in the Schema Designer
- Relate Two Data Models
Screens
Weather Lookup Series — guided 3-part build
- Part 1 · Build the Screen (Beginner)
- Part 2 · Store the Readings (Intermediate)
- Part 3 · Watched Locations & Scheduled Capture (Advanced)
Data Flows & Integrations
- Call an External API with a Flow
- Connect to External Systems
- Create a Data Flow
- Create a Notification Channel
- Create a Webhook
- Save Queries, Scripts, and Data Mappings
- Schedule a Data Flow
- Use the Script Editor
Data, Reporting & Monitoring
- Browse Data with Data Explorer
- Build a Document (Report or Label)
- Check Component References
- Create Configuration Records (Modules, Units, Calendars, and More)
- Explore the GraphQL API
- Export Data
- Import Data into an Application
- Investigate Application Logs
- Save an Export Configuration
- Trace a Data Change
Enterprise & Organizations
Platform Concepts & Architecture (10)
- Bridging the Red and Blue Data Divide - How Fuuz Became the First Industrial Platform to Merge Operational and Business Intelligence
- Claude AI Skills for the Fuuz Platform
- Cool Things we built with Fuuz Episode 1 12.5.2025 (Public)
- Differences between MES and ERP from an ERP Consultant Eric Kimberling
- Fuuz can be your "Connected Worker Platform"
- Listen and Learn what MES is and what makes it unique
- Manufacturers struggle with Build versus Buy for their MES and what are the Core 4 Elements
- Stock Price Application
- Why All Manufacturers Build their MES System Part 1
- Why All Manufacturers Build their MES System Part 2
Screens & Application Design (17)
- Application Designer Guide
- Array Input
- Combobox
- Dynamic Field Configurations
- Fuuz Deployment Methodologies
- Fuuz Form Detail Screen Specification
- Historical Data Table Screen Design Standard
- JSON
- JSON Form Fields in Action Steps
- JSON Schema Inputs
- Master Data Table Screen Design Standard
- Mobile Screen Design Standard
- Screen Context Container
- Screen Generation (AI) Flow Template V1.5.1
- Setup Data Table Screen Design Standard
- Table Column Conditional Formatting
- Transform Data in a Column
Data Models & Schema (8)
Data Flows & Scripting (51)
Designing Flows
- Data Flow Design Standards
- Data Flow Logs
- Debugging and Testing our Fuuz Data Flows
- Flow Schedules
- Fuuz Data Flows enable DataOps at Scale, ETL, iPaaS and more
- How to Create APIs Using Data Flows in Fuuz
- How To General E-Commerce Integrations using Data Flows in Fuuz iPaaS
- How to Setup a daily file import using Fuuz Data Flows
- Managing Large Datasets in Fuuz: Data Flow Engine Performance Optimization
- The Power of Data Flows - Unlocking Industrial Intelligence with Fuuz
- Using Fuuz with FTP integrations and Data Flows iPaaS
Data Flow Nodes
- Data Flow Nodes Reference
- Debugging & Context Nodes
- Flow Control Nodes
- Fuuz Platform Nodes
- IIoT & Gateway Nodes
- Integration Nodes
- Notification Nodes
- Source & Trigger Nodes
- Transform Nodes
JSONata Reference
- Aggregation Functions
- Array Functions
- Boolean Functions
- Boolean Operators
- Comparison Operators
- Composition
- Construction
- Constructs
- Custom Fuuz Only JSONata Library
- Date Time Functions
- Date Time Processing
- Expressions
- Fuuz Bindings: $predicateFilter
- Higher Order Functions
- Jsonata Tutorial
- Numeric Functions
- Numeric Operators
- Object Functions
- Other Operators
- Path Operators
- Predicate Expressions
- Processing Model
- Regex
- Simple Queries
- Slow Transform Performance: JSONata vs JavaScript Optimization Guide
- Sorting Grouping and Aggregation
- String Functions
Scripting
Integrations & Connectors (30)
General & iPaaS
- API Keys
- Cloud Connectors - Complete Reference Guide
- Connecting a CRM with your ERP using Fuuz
- Connecting a Vending Machine to your ERP system using Fuuz
- Creating a Scheduled Integration & Sending a CSV File in an Email
- Debug a NetSuite SOAP API integration
- Fuuz Connections help you integrate your Systems and Devices
- Fuuz has lists of Connectors and Drivers you can use
- Fuuz has pre-built integration Connectors
- How to create a check an ODBC connection with another system
- How to Create a RESTful API Using the Fuuz Platform
- How to create a simple Integration and Store data in Fuuz
- How To Design or Configure Policies and Policy Groups for my App in Fuuz
- How to Integrate Fuuz with another product or another API
- How to Integrate with an HR system like ADP using Fuuz iPaaS
- How to use API Explorer and GraphQL to Query Data in Fuuz for Beginners
- How you Integrate your ERP with your MES
- Industry 3 and Industry 4 differences in ERP and MES Integrations
- Integrated Carrier Package
- Make REST-Based Calls With An API Key
- Policy Groups
- System connectivity validation - testing a connection when your 3rd party moves its hosting
- Using Fuuz as an iPaaS to Connect - to an API, Collect - Data from the API, Store - that data in Fuuz tables
Plex
- How to connect using Plex UX datasources from Fuuz iPaaS
- How to integrate with Plex Classic using Fuuz iPaaS
- How to Setup and Connect to Plex APIs
EDI
IIoT & Edge Gateway (18)
- Edge Connections: Complete Industrial Integration Reference
- Edge Gateway Flows
- Edge Gateway Installation Step-by-Step
- Edge to Cloud Infrastructure
- Gateway Deployment & Architecture
- Gateway System Requirements
- How IIoT fits into the Industrial Data "Stack"
Physical Device Connectors
- Connecting To Kepware OPCUA Server
- Fanuc Robot Connectivity using Edge Gateway
- HMI Template Standard - ISA-101 Compliant
- How to connect OPC/UA simulator to the Edge Gateway
- Modbus TCP
- MQTT
- Omron PLC/HMI NX102 Connectivity with Edge Gateway
Edge Data Connectors
Reporting, Documents & Dashboards (8)
- Building a Non-Conformance Report (NCR) Application in Fuuz
- Create responsive structured dashboard layouts using the Grid Container and Grid Cell components
- How to add visualizations (charts and graphs) to reports in Fuuz for Beginners
- How to build real-time reports in Fuuz from scratch for Beginners
- How to modify existing reports in Fuuz for Beginners
- Non-Conformance Report Accelerator
- Printing Documents
- Printing Documents From Fuuz
Administration & Access Control (27)
- Access Control
- Access Requests
- Access Requests: Overview
- Access Type Overview
- Access Types
- Add Users to Fuuz Apps
- App Admin Access
- App Management
- App Users
- Applications (Tenants)
- Authentication Events
- Change a User's Access Type
- Configurations
- Create Users and Set Access Type
- Enterprise Admin Overview
- Enterprise Users
- Enterprise Users vs Access Requests
- How To Login to your Fuuz Enterprise - Non Single Sign On
- How To Login to your Fuuz Enterprise - Single Sign On
- Identity Providers
- Notifications
- Notifications
- Organizations
- Roles
- Settings
- Switching my active Role within Fuuz
- Troubleshooting User Login Errors Due to Identity Provider Misconfiguration
Data Management (8)
Accelerators, Templates & Packages (8)
- Create a Quality Batch Golden Record Analysis Tool in Fuuz
- Fuuz Developer 101 Bootcamp - 2026 Schedule & Enrollment
- Fuuz Developer 101 Bootcamp - Program Overview
- Fuuz Industry Accelerators - Installation & Best Practices
- Fuuz Industry Accelerators - Overview
- How-To: Managing Green/Blue Deployments with Fuuz Package Management Zero-Downtime
- Model Agnostic Scheduling System APS
- Setting up In-House Fuuz
Design Standards (1)
How-To Guides (8)
- Connecting to Fuuz from a remote system to execute a Fuuz API
- Connecting to Fuuz from a remote system to execute a Fuuz API - Extended Features Part 2
- Data Mapping
- Document your Application using Atlassian Confluence and our Pre-Built App
- Fuuz Platform Capabilities
- How to add multiple data records to the Fuuz database with a single API call
- How to on Best Practices for Designing Flows in Fuuz
- Using the Transformation Explorer
FAQ & Troubleshooting (1)
Release Notes (117)
2026
- 2026.1 (January 2026)
- 2026.2 (February 2026)
- 2026.3 (March 2026)
- 2026.4 (April 2026)
- 2026.5 (May 2026)
- 2026.6 (June 2026)
2025
- 2025.1 (January 2025)
- 2025.10 (October 2025)
- 2025.11 (November 2025)
- 2025.12 (December 2025)
- 2025.2 (February 2025)
- 2025.4 (April 2025)
- 2025.5 (May 2025)
- 2025.6 (June 2025)
- 2025.7 (July 2025)
- 2025.8 (August 2025)
- 2025.9 (September 2025)
2024
- 2024.1 (January 2024)
- 2024.10 (October 2024)
- 2024.11 (November 2024)
- 2024.12 (December 2024)
- 2024.2 (February 2024)
- 2024.3 (March 2024)
- 2024.4 (April 2024)
- 2024.5 (May 2024)
- 2024.6 (June 2024)
- 2024.7 (July 2024)
- 2024.8 (August 2024)
- 2024.9 (September 2024)
2023
- 2023.5 (May 2023)
- 2023.1 (January 2023)
- 2023.10 (October 2023)
- 2023.11 (November 2023)
- 2023.12 (December 2023)
- 2023.2 (February 2023)
- 2023.3 (March 2023)
- 2023.4 (April 2023)
- 2023.6 (June 2023)
- 2023.7 (July 2023)
- 2023.8 (August 2023)
- 2023.9 (September 2023)
2022
- 2022 Q1 Fuuz Package Updates (03/11/2022)
- 2022 Q1 Fuuz Release Notes v3.87.0 (03/17/2022)
- 2022 Q1 MFGx Release Notes v3.78.0 (01/06/2022)
- 2022 Q1 MFGx Release Notes v3.79.0 (01/13/2022)
- 2022 Q1 MFGx Release Notes v3.80.0 (01/20/2022)
- 2022 Q1 MFGx Release Notes v3.81.0 (01/27/2022)
- 2022 Q1 MFGx Release Notes v3.82.0 (02/03/2022)
- 2022 Q1 MFGx Release Notes v3.83.0 (02/10/2022)
- 2022 Q1 MFGx Release Notes v3.85.0 (02/28/2022)
- 2022 Q2 Fuuz Release Notes v3.90.0 (04/14/2022)
- 2022 Q2 Fuuz Release Notes v3.91.0 (04/21/2022)
- 2022 Q2 Fuuz Release Notes v3.92.0 (04/28/2022)
- 2022 Q2 Fuuz Release Notes v3.93.0 (05/06/2022)
- 2022 Q2 Fuuz Release Notes v3.94.0 - v3.97.0 (June 13, 2022)
- 2022 Q2 Fuuz Release Notes v3.98.0 (06/16/2022)
- 2022 Q2 Fuuz Release Notes v3.99.0 (06/30/2022)
- 2022 Q3 Fuuz Release Notes v3.100.0 🎉 (07/06/2022)
- 2022 Q3 Fuuz Release Notes v3.101.0 (07/21/2022)
- 2022 Q3 Fuuz Release Notes v3.102.0 (08/11/2022)
- 2022 Q3 Fuuz Release Notes v3.103.0 (08/18/2022)
- 2022 Q4 Fuuz Release Notes v3.107.0 - v3.109.0 (10/27/2022)
2021
- 2021 Q1 MFGx Release Notes v3.29.0 (1/7/2021)
- 2021 Q1 MFGx Release Notes v3.30.0 (1/14/2021)
- 2021 Q1 MFGx Release Notes v3.34.0 (2/4/2021)
- 2021 Q1 MFGx Release Notes v3.37.0 (2/26/2021)
- 2021 Q1 MFGx Release Notes v3.38.0 (3/5/2021)
- 2021 Q1 MFGx Release Notes v3.40.0 (3/25/2021)
- 2021 Q1 MFGx.io Release Notes v3.32.0 (1/21/2021)
- 2021 Q1 MFGx.io Release Notes v3.33.0 (1/28/2021)
- 2021 Q2 MFGx Release Notes v3.41.0 (4/1/2021)
- 2021 Q2 MFGx Release Notes v3.42.0 (4/8/2021)
- 2021 Q2 MFGx Release Notes v3.43.0 (4/16/2021)
- 2021 Q2 MFGx Release Notes v3.44.0 (4/22/2021)
- 2021 Q2 MFGx Release Notes v3.45.0 (4/29/2021)
- 2021 Q2 MFGx Release Notes v3.47.0 (5/13/2021)
- 2021 Q2 MFGx Release Notes v3.48.0 (5/20/2021)
- 2021 Q2 MFGx Release Notes v3.48.0 (5/27/2021)
- 2021 Q2 MFGx Release Notes v3.50.0 (6/03/2021)
- 2021 Q2 MFGx Release Notes v3.51.0 (6/10/2021)
- 2021 Q2 MFGx Release Notes v3.52.0 (6/17/2021)
- 2021 Q2 MFGx Release Notes v3.54.0 (6/28/2021)
- 2021 Q3 Fuuz Release Notes v3.58.0 (7/22/2021)
- 2021 Q3 MFGx Release Notes v3.55.0 (7/1/2021)
- 2021 Q3 MFGx Release Notes v3.60.0 (8/5/2021)
- 2021 Q3 MFGx Release Notes v3.61.0 (8/17/2021)
- 2021 Q3 MFGx Release Notes v3.62.0 (8/19/2021)
- 2021 Q4 MFGx Release Notes v3.68.0 (10/8/2021)
- 2021 Q4 MFGx Release Notes v3.69.0 (10/14/2021)
- 2021 Q4 MFGx Release Notes v3.70.0 (10/21/2021)
- 2021 Q4 MFGx Release Notes v3.71.0 (10/28/2021)
- 2021 Q4 MFGx Release Notes v3.72.0 (11/04/2021)
- 2021 Q4 MFGx Release Notes v3.73.0 (11/11/2021)
- 2021 Q4 MFGx Release Notes v3.74.0 (11/19/2021)
- 2021 Q4 MFGx Release Notes v3.75.0 (12/02/2021)
- 2021 Q4 MFGx Release Notes v3.76.0 (12/09/2021)
- 2021 Q4 MFGx Release Notes v3.77.0: The Holiday Update (12/16/2021)
2020
- 2020 Q2 MFGx Release Notes v2.32.0 (4/9/2020)
- 2020 Q2 MFGx Release Notes v2.33.0 (4/16/2020)
- 2020 Q2 MFGx Release Notes v2.35.0 (4/30/2020)
- 2020 Q2 MFGx Release Notes v3.5.0 (6/18/2020)
- 2020 Q2 MFGx Release Notes v3.6.0 (6/25/2020)
- 2020 Q2 MFGx.io Release Notes v2.32.0 (4/9/2020)
- 2020 Q3 MFGx Release Notes v3.10.0 (7/23/2020)
- 2020 Q3 MFGx Release Notes v3.11.0 (7/30/2020)
- 2020 Q3 MFGx Release Notes v3.13.0 (8/13/2020)
- 2020 Q3 MFGx Release Notes v3.17.0 (9/21/2020)
- 2020 Q3 MFGx Release Notes v3.7.0 (7/6/2020)
- 2020 Q3 MFGx Release Notes v3.8.0 (7/9/2020)
- 2020 Q4 MFGx Release Notes v3.20.0 (10/13/2020)
- 2020 Q4 MFGx Release Notes v3.21.0 (10/15/2020)
- 2020 Q4 MFGx Release Notes v3.22.1 (10/22/2020)
- 2020 Q4 MFGx Release Notes v3.23.0 (11/5/2020)
- 2020 Q4 MFGx Release Notes v3.24.0 (11/12/2020)
- 2020 Q4 MFGx Release Notes v3.26.0 (12/3/2020)
- 2020 Q4 MFGx Release Notes v3.27.0 (12/10/2020)
- 2020 Q4 MFGx Release Notes v3.28.0 (12/17/2020)