Developer Info

Building out your project with also builds out a Rest API at the same time. Use it to interact with your data from applications in another language than those supported by embedding.


While <> provides an easy to use form builder and embeddable interface directly into your applications, sometimes it is necessary to be able to access the API directly. <> will automatically build out your Rest API for you as you build your form and you are able to perform normal Restful requests directly to the API if you want. Because of how <> is built, you can log in with your <> account and get access to all the resources in your project. We do not recommend this for client facing applications though as you could expose your credentials to them. You can set up a User Resource inside your project to authenticate against to allow your users to use their own credentials and have access to restricted resources.

For a complete walkthrough on how to build an application using, we recommend watching the following video.

Angular.js Embedding

<> has an Angular module that allows building out forms and APIs on <> and then embedding everything directly into your application with one line of code. When using this method, there is no other work needed to allow users to create, edit and delete resources within your application and when you make changes to the forms, they immediately update within your application.

The normal process to embed is to use bower to install the formio component with bower install ng-formio and then include all the dependencies in your html files with either gulp wiredep or manually. You can see examples of this inside our sample applications at

To make the process simpler for those who only need to embed on a website, we provide a build file, formio-full.js, with all dependencies already included. It can be found at Include this script on the page and instantiate an angular application with a dependency on formio and you can then directly embed forms.

Here is a working jsfiddle of the simplest way to do an embed.

Adding the Formio Module

In order to embed your <> project in your angular application, you will need to add the formio module. The formio module will create all scopes, providers and directives needed to embed <> components within your app.


To add formio to your bower dependencies, run bower install --save ng-formio.

Adding the dependencies

Formio requires some dependencies on your HTML page to work properly. All of these dependencies can be found by looking at the formio bower.json file. The easiest way to include all of these dependencies within your webpage is to use a tool called Wiredep.


First you need to install wiredep.

  npm install -g wiredep

Next, add the following to your HTML page:

      <!-- bower:css -->
      <!-- endbower -->
      <!-- bower:js -->
      <!-- endbower -->

Next, run the following command to wire up all the dependencies.

  wiredep -s index.html

This should then wire all the dependencies into your page.

Example Page

To see this in action, here is an example page with all the dependencies already wired up for reference.

Initialize Angular

The next step is to initialize formio within your Angular application. This requires you to add the following to your angular.js declaration.

angular.module('myApp', ['formio']);

And of course, if you are not using Angular for your full application, you will need to make sure that the application name is provided on the <body> tag.

<body ng-app="myApp">


formio Directive forms can be embedded direction into your angular application with one line of code. Simply pass in the name of the form to the directive and the formio module will render out the form for you. If you only pass in the form name, a form with default values will be rendered. This is useful for Creating new submissions.

<formio src="''"></formio>;

Rendering Submission in Form

You can also render out a form for a previous submission with the values already set in it. This is useful for Editing functionality to allow users to edit previous submissions.

<formio src="'[submissionId]'"></formio>

Read-only Submissions in Form

You can provide a read-only flag to the formio directive which will tell the form to render as a Read only form where the data is populated but cannot be edited. This is good for Printable form submissions as well as viewing a form submission.

<formio src="'[submissionId]'" read-only=true></formio>


The URL of the form or form submission to display.
The URL of the custom form action to handle submissions. If this attribute is provided, form submissions will be sent to that URL instead of This is helpful if you need to pre-process data before sending it to
An Object definition of the form to display. This can be used as an alternative to loading form definitions from the src attribute.
An Object containing submission data to display. This is useful if you have already loaded submission data you wish to display on this form.
Makes form fields read only, which can be useful for Viewing submission results.
An Object containing options to pass to Formio.js, often used with Formio.js plugins.

formioSubmissions Directive

In addition to forms that create submissions, the formioSubmissions directive can embed lists of previous submissions within your application. This is useful for creating lists of items to display within your applications.

<formio-submissions src="''"></formio-submissions>


The URL of the form to display the submissions of.
An Object definition of the form to display. This is helpful if you have already loaded the form that corresponds to the submission data.
An Array of submission data Objects to display. This is helpful if you have already loaded submissions you wish to display.
The number of submissions to list per page.

formioDelete Directive

This directive will show a delete confirmation dialogue and will, on confirmation, delete a form or submission. This directive triggers the cancel or a delete events depending on user input.

<formio-delete src="'[submission_id]'"></formio-delete>


The URL of the form or submission to delete.
Alternatively, you can pass in the form definition as an attribute on the formio directive.
If a submission has already been loaded, it can be passed in as an attribute.
The URL of the custom form action to handle delete requests. If this attribute is provided, HTTP DELETE requests will be sent to that URL instead of This is helpful if you need to pre-process data before deleting it from
The resource name used in the delete dialogue for confirmation. If not provided, it will default to "form" or "submission", depending on the src attribute passed in.

Formio Events

The formio module emits events at various times. These events are designed to allow developers to respond to events that occur within the formio generated forms. For example, after a user creates a new submission, you may want to change the view to display that submission or send them to a thank you page. You can do this by responding to the formSubmission event:

$scope.$on('formSubmission', function(err, submission) { /* ... */ })

The following are all the events emitted by the above directives:

Called after a form is submitted, but before it has been sent to the server. This submission can be cancelled by calling `event.preventDefault()`.
submission: The submission that was submitted.
Called after a form is successfully submitted to the server. This can be either a create or an edit.
submission: The submission that was submitted.
Called whenever client side validation fails.
error: The error that occurred.
Called whenever a form is loaded from the server. This is useful to customize forms before they are displayed.
form: The form that was loaded.
Called whenever the view button is clicked in a `formioSubmissions` directive.
submission: The submission that is being viewed.
Called whenever the edit button is clicked in a `formioSubmissions` directive.
submission: The submission that is being edited.
Called whenever the delete button is clicked in a `formioSubmissions` directive.
submission: The submission that is being deleted.
Called whenever a submission is loaded from the server.
submission: The submission that was loaded.
Called whenever multiple submissions are loaded from the server.
submissions: An array of submissions that were loaded.
Called whenever a delete dialog is cancelled.
Called whenever a delete dialog is confirmed and a submission is deleted.
data: The data that was returned from the delete request.

Styling Forms

Since embedding <> forms embeds them directly in your HTML pages instead of using iframes, you can easily add CSS styles to your application to customize form appearances.

Every form component is wrapped in a <div> with the class name form-field-type-{fieldType}. Use this to style all fields of a certain type. For example, to style only checkbox fields, you may have CSS that looks like this:

.form-field-type-checkbox {
    // Your styles go here...

The same <div> wrapping each form component also is given an id in the form form-group-{fieldKey}. The fieldKey corresponds to the unique Property Name given to each form component. You can find this in the API tab of the form component settings. Use this id to style a single specific form element. For example, to style a field with the key fullName, you may have CSS that looks like this:

#form-group-fullName {
    // Your styles go here...

Finally, you can configure most components with a custom CSS class that will be used when rendering the form. You can specify multiple class names by separating them with single spaces.

Conditional Fields

A frequent request is to have fields show and hide based on values in other fields. Building a fully functional UI for this would make using it daunting so instead we have enabled this through programming.

To have conditional fields, create a controller that wraps the form and send the submission variable into the form. Then watch the submission variable using $scope.$watch and then affect the displayed forms as needed. This will allow maximum flexibility into showing and hiding forms.

Here is a working example of showing and hiding fields in a jsfiddle. Feel free to try it out and modify it.

Form Translation

You can translate your <> forms by wrapping Angular-Translate in your application.

There are a two ways of achieving this.

  1. You can call
$translateProvider.translation('en', {
  'Original String': 'Translated String'

This will register a new language to the translation provider. The Original String is the string within the form that you want to translate. It could be the field label, placeholder or dropdown value. You can include multiple strings in the language definition.

  1. You can include the translations in external files with or other loaders.

From then on, use angular-translates language switching capability and the form will translate itself.

Offline Mode

We provide a plugin to users with Team Pro or Enterprise projects that enables their applications to request and submit forms offline.

The plugin provides offline mode support for a single project. Offline requests will automatically kick in when a request fails due to a network error and serve data cached offline, if available. You may also create/edit/delete submissions while offline, and the requests will be queued to be sent when the app goes back online.

Example Application

To help with the implementation of Offline Mode, we have contributed an Open Source application that incorportes our offline mode capabilities. This application is called the GPS Tracker. To quickly bootstrap this project to test locally you can run the following CLI command.

npm install -g formio-cli
formio bootstrap formio/formio-app-gpstracker

The following documentation serves to show you how to add this capability into your own project.

Adding Offline Mode to your Project

To add offline mode to your project, you must first upgrade your project to Team Pro or Enterprise. Once you do this, you will then be added to our Offline Mode Github project which will allow you to include it within your application. To do that you will use bower and type the following.

bower install --save

You will also need to include the following project dependencies which will be needed to build the offline manifest as well as include the offline mode in your project.

npm install --save-dev gulp-manifest
bower install --save ng-formio-helper

Once you do this, you can then include the Offline mode into your application by including the ngFormioHelper library.


(function() {
  'use strict';
    .module('myApp', [

Create the application manifest

Now that the Offline mode has been added to your project, you will now need to create the applicatoin manifest for the application cache capability. We can use Gulp to help out with this, by including the following Gulp tasks within our build routines.


gulp.task('offline', ['html', 'config', 'fonts', 'other'], function() {
  return gulp.src([path.join(conf.paths.dist, '/**/*')], { base: './dist/' })
      hash: true,
      preferOnline: true,
      network: ['*'],
      filename: 'app.manifest',
      exclude: ['app.manifest', 'maps/**']

and then register it to the build task.

gulp.task('build', ['html', 'fonts', 'other', 'views', 'config', 'offline']);

We now need to add the manifest to our index.html file.


<html manifest="app.manifest" ng-app="myApp">

Register Offline Mode within your application.

To get offline mode working in your application, we will use the Formio helper library to register our application with offline mode support. We start this within the config method of our Angular.js app which defines our routes.


/** @ngInject */
function routeConfig(
) {

    errorUrl: '/error',
    homeState: 'home'

We now need to initialize this within the application using the following.


    ) {
      // Initialize offline mode for your application.

Add the offline button to the header

The next thing you need to do is add the Offline mode button to your header of your application. This will allow you to syncronize the submissions that have been captured within offline mode. You can do that with the following <offline-button> directive code in your applications navbar.

<div id="navbar" class="navbar-collapse collapse">
  <ul class="nav navbar-nav navbar-right">

Once you do that you should now have offline capabilities within your application!

How it works - The API

The offline mode plugin uses the renderer plugin system to hook into each request using the following registration process.

var plugin = new FormioOfflinePlugin('', 'path/to/project.json');
Formio.registerPlugin(plugin, 'myproject-offline');

// You can later access the plugin with:
// var plugin = Formio.getPlugin('myproject-offline');

new FormioOfflinePlugin(projectUrl, [projectJsonPath])

The constructor accepts two arguments. The projectUrl should point to the project that offline mode should be enabled for. The optional projectJsonPath must be the path to a exported project.json file to use to initialize the offline forms (If your app starts while offline, the forms in the project.json can still be successfully requested).

Saving forms and submissions offline

Once you register a plugin for a particular project, all load requests for forms and submissions in that project will automatically save and update in an offline browser data store.

For example, you can have all submissions for a form available offline if you call formio.loadSubmissions() at some point in your app while online.

Loading forms and submissions offline

When your app goes offline, requests to load a form or submission will automatically return the data cached offline, if available.

Submitting forms offline

Form submissions work a little bit differently when this plugin is registered. All form submissions, submission edits, and submission deletions are added to a queue. If the app is online, the queue will be emptied immediately and behave like normal. But when the app is offline, the submissions stay in the queue until the app goes back online. Until then, Formio.js will behave as if the submission was successful.

The queue will automatically start to empty when a submission is successfully made online, or you may manually start it.

Handling submission queue errors

Some queued submissions may fail when they are sent online (ex: unique validation fails on the server). In the event a queued submission fails, the queue is stopped and events are triggered to allow your app to resolve the bad submission before continuing. It’s up to your app to decide how to handle these errors. Your app may decide to prompt the user to fix the form submission or simply ignore the submission, and restart the queue.

Plugin methods


Forces all requests for this plugin’s project into offline mode, even when a connection is available.


Returns true if this plugin is currently forced offline.


Clears all offline data. This includes offline cached forms and submissions, as well as submissions waiting in the offline queue.


Starts to process the submission queue. All requests in the offline submission queue will be sent in the order they were made. Successful requests will either resolve their original promise or trigger the offline.formSubmission event from A failed request will stop processing the queue and trigger the offline.formError event. The app must handle this event to resolve the failing requests and restart the queue.


Returns the number of submission requests currently in the offline queue.


Returns the next request in the submission queue.


Sets the next request in the submission queue to request.

You can use this to fix a failed submission and then call dequeueSubmissions() to resubmit and continue the queue.


Discards the next request in the submission queue.

You can use this to ignore a failed submission and then call dequeueSubmissions() to continue to the next queued request.


You can listen for these events by adding listeners to the EventEmitter.

NOTE: if you are using the Angular ngFormio library, you can listen for these events in the Angular scope by adding formio. before each event name.


Triggered when a submission is added to the submission queue.


Triggered when the submission queue starts to process a submission.


Triggered when a submission fails and is added back to the front of the submission queue.


Triggered when a queued submission is successfully submitted. This is not called if the original promise of the request can be resolved (in which case it behaves like a normal online submission).


Triggered when a queued submission returns an error. This means the app needs to either fix the submission or skip it, and restart the queue.


Triggered when the queue becomes empty after dequeuing.

Request Options


You may set skipQueue to save a submission immediately, skipping the queue. This will disable offline queuing for that submission. For example:

formio.saveSubmission(submission, {skipQueue: true});

If you are using the Angular ngFormio library, you can set the skipQueue option with formio-options:

<formio src="userLoginForm" formio-options="{skipQueue: true}"></formio>

Login with Email

In addition to providing full authentication capabilities, also provides a very robust method for Automatic Logins via Email. There are many use cases where Email Login is utilized including, but not limited to…

  • Email Registrations (where they must click on a link in their email to register)
  • Email Reset Password

To make this happen, there is a special token that can be added to the message of your email action and templates. This token will generate a special JWT token to log in the person who the email was addressed to. This token is defined as follows.


Which is defined as follows…

  • LOOKUP_FIELD - This is the field that is used to search for the record we wish to login. This works by taking the value provided in the Email To: Address and searching the resource with that value as that field.
  • LOOKUP_RESOURCE - This is the resource to lookup when establishing the token.

Important Note - This will ONLY create a token if the persons email address that is being sent the email is found within the resource.

For example, lets say you have a Resource as Customer and a field within that resource called Email you wish to create a token for. Now lets say you wish to send an email to one of your customers to complete their registration via email. This may look like the following.

  Subject: Register Now
  Message: Click here to complete your registration[[token(]]#register

This following email performs the following:

  • Looks up within the customer Resource.
  • If a record is found, it generates a temporary token and replaces [[token(]] with that token.
  • Tells the application to navigate to the #register state once the authentication has been performed.

This turns this email into something that looks like the following.

  Subject: Register Now
  Message: Click here to complete your registration

Application Changes to handle Email Tokens

Once you have the email being sent, this single sign on URL will direct them to the Serverless application which needs to handle the token. This requires a minor change within your application to accept the token and then reset the localStorage value with the new token. The library will then take it from there and authenticate all future requests with that token. You can make this change by adding the following to your /app/config.js file.

// Parse query string
var query = {};"&").forEach(function(item) {
  query[item.split("=")[0]] = item.split("=")[1] && decodeURIComponent(item.split("=")[1]);

// This is what you will need to add to your application.
if (query.token) {
  localStorage.setItem('formioToken', query.token);
  window.history.pushState("", "", location.pathname + location.hash);

Once you have implemented this, your application should then be able to handle an automatic email authentication into your application.

Login with Auth0

A very common use case with is to integrate it with the amazing authentication platform called Auth0. This integration can be used to bring the following functionality into your application.

  • Passwordless logins
  • OAuth implementations
  • Reset Password
  • Breached password capability

The following talks about how you can implement this service within a application.

Adding Rules to Auth0

After you create your Auth0 account, you will first want to create a new Rule within your account.

  • Click on the section called Rules
  • Click on the button that says Create Rule
  • Select Empty Rule
  • Give your rule a title such as Formio Integration
  • Within the contents, copy and paste the following.
function (user, context, callback) {

  // Your Project API

  // Secret password used for all accounts (KEEP THIS SECRET!)
  var FORMIO_DEFAULT_PASS = 'user-default-password-secret';

  // skip if no email
  if(! return callback(null, user, context);

   * Check to see if a user exists.
   * @param email
   * @param next
  var userExists = function(email, next) {
      uri: FORMIO_PROJECT_API + '/user/exists',
      method: 'GET',
      qs: {
        '': email
    }, function(error, response) {
      var status = parseInt(response.statusCode, 10);
      if (status === 200) {
        return next(null, true);
      else if (status === 404) {
        return next(null, false);
      return next(error);

   * Register a new user provided the default password and user info.
   * @param userInfo
   * @param next
  var registerUser = function(userInfo, next) {
    userInfo.password = FORMIO_DEFAULT_PASS;
      uri: FORMIO_PROJECT_API + '/user/register',
      method: 'POST',
      json: {
        data: userInfo
    }, function(error, response) {
      if (error) {
        return next(error);
      next(null, response.headers['x-jwt-token']);

   * Log in the user using the email and default password.
   * @param email
   * @param next
  var loginUser = function(email, next) {
      uri: FORMIO_PROJECT_API + '/user/login',
      method: 'POST',
      json: {
        data: {
          email: email,
          password: FORMIO_DEFAULT_PASS
    }, function(error, response, data) {
      if (error) {
        return next(error);
      next(null, response.headers['x-jwt-token']);

   * Retrieve a user token. This accomplishes this task using a few steps.
   *   1.) Check to see if the user exists within
   *   2.) If yes, then we will simply log the user in with the default password.
   *   3.) If no, then we will register them into the system which also logs them in.
   * @param userInfo - The user information passed to us from Auth0.
   * @param next
  var getUserToken = function(userInfo, next) {
    userExists(, function(err, exists) {
      if (err) {
        return next(err);
      if (exists) {
        loginUser(, next);
      else {
        registerUser(userInfo, next);

  // Get the user token.
  getUserToken(user, function(err, jwtToken) {
    // Let the user know if an error occured.
    if (err) {
      return callback(err);

    // Add the JWT token to the user metadata and return.
    user.user_metadata = user.user_metadata || {};
    user.user_metadata.formio = {token: jwtToken};
    auth0.users.updateUserMetadata(user.user_id, user.user_metadata);
    return callback(null, user, context);

Auth0 + integration

Now that you have a rule setup, the next step is to create an application and integrate within that application. For this example, we will start with an application provided by Auth0 found @

Once you download this application, you will need to install all dependencies by typing.

bower install

You will then need to install the formio.js library by typing the following.

npm install formiojs

And then provide the following within the /index.html file.

<script type="text/javascript" src="node_modules/formiojs/dist/formio.min.js"></script>

Once you do that, you can then put the following within the /auth0-variables.js file.

var FORMIO_API = '';

Now, within the /app.js file, we will need to initialize the Formio library with the following.

function config($stateProvider, lockProvider, $urlRouterProvider) {


And finally, within the /components/auth/auth.service.js file, we will need to alter the service to set the JWT token with the one that we provided to the Auth0 Rule.

function authService(lock, authManager) {

    function login() {;

    // Logging out just requires removing the user's
    // id_token and profile
    function logout() {

    // Set up the logic for when a user authenticates
    // This method is called from
    function registerAuthenticationListener() {
      lock.on('authenticated', function (authResult) {
        localStorage.setItem('id_token', authResult.idToken);
        lock.getProfile(authResult.idToken, function (error, profile) {

    return {
      login: login,
      logout: logout,
      registerAuthenticationListener: registerAuthenticationListener

Now, when you log into Auth0, you will automatically connect to a User within your application creating a seamless authentication between the two platforms!

Auth0 + Example App

If you would like to see an example application that uses this integration go here.

Go to + Auth0 Example Project

React.js Embedding

<> has a React module that allows building out forms and APIs on <> and then embedding everything directly into your application with one line of code. When using this method, there is no other work needed to allow users to create, edit and delete resources within your application and when you make changes to the forms, they immediately update within your application.

The react-formio module can be found at

Adding the React Module


React Formio can be used on the server, or bundled for the client using an npm-compatible packaging system such as Browserify or webpack.

npm install react-formio --save

Browser bundle

The browser bundle exposes a global Formio variable and expects to find a global React variable to work with.

You can find it in the /dist directory.

Using the React Module

Give Formio a src property and render:

var React = require('react');
var Formio = require('react-formio');

// React <= 0.13
  <Formio src="https://example.formio/example" />
  , document.getElementById('example')

// React >= 0.14
var ReactDOM = require('react-dom');

  <Formio src="https://example.formio/example" />
  , document.getElementById('example')


src : string

The form API source from or your custom formio server.

See Creating a Form for where to set the API Path for your form.

You can also pass in the submission url as the src and the form will render with the data populated from the submission.

form : object

An object representing the form. Use this instead of src for custom forms.

Note: src will override this property if used.

submission: Object

An object representing the default data for the form.

Note: src will override this if a submission url is entered.

onFormSubmit : (submission: object)

A function callback that will be called when a submission is successful.

onFormError : (response: object)

A function callback that will be called when a submisison is unsuccessful.

onFormLoad : (form: object)

A function callback that will be called with a form is finished loading.

onSubmissionLoad : (submission: object)

A function callback that will be called after a submission is loaded.

onElementRender : (element: object)

A function callback that will be called each time a component is rendered.

Apache Cordova

Applications built with can be deployed using Apache Cordova. Apache Cordova allows compiling web applications into binary apps that can be run on modern mobile devices such as iOS and Android phones. The applications are then distributed as mobile applications instead of being published on the web.

Project Setup

The first step in generating a Cordova based application is to ensure that you have cloned and built your project. If you are using one of our templates as a starting point this should be fairly straightforward. We’ll be using formio-app-todo as a demo for how to do this.

First, clone the app and install the required dependencies. You can follow the steps in the portal at Launch->Local App Development.

git clone
cd formio-app-todo
npm install -g bower
npm install
bower install

Next make sure you’ve created a todo app on and update the config to point to your project url.

In the /src/config.js file.

var APP_URL = '';

You can test out the app by running

gulp serve

Finally, build a deployable version of the app into the /dist directory by running.

gulp build

If you are not using one of our templates, use whatever build mechanisms you have set up.

Cordova Install

The next step is to ensure that Cordova is installed on your computer so that you can create the cordova project and begin compiling to apps.

You can follow the more detailed instructions of how to install Cordova at Create your first Cordova app

Here are the basic steps. Run them from the root of your project

# Install cordova's command line
npm install -g cordova
# Create the cordova project in the cordova directory
cordova create cordova
# Change to the cordova directory to make further changes
cd cordova
# Add iOS and Android platforms
cordova platform add ios --save
cordova platform add android --save

Next you’ll want to install all the pre-requisites for building the applications. To check which pre-requisites are needed and their current status, run:

cordova requirements

Install the pre-requisites and rerun the command until all pre-requisites are met.

For information on installing the pre-requisites, see Cordova’s documentation at

Cordova should now be ready to build applications.


Cordova uses plugins to connect some device capabilities to your web application. In order to take advantage of these capabilities, you’ll need to install the corresponding plugins.

If you have any file fields inside your application, you’ll want to allow the app to access files, media and the camera so files can be uploaded to it. Use these plugins

cordova plugin add cordova-plugin-file --save
cordova plugin add cordova-plugin-media --save
cordova plugin add cordova-plugin-camera --save
cordova plugin add cordova-plugin-file-transfer --save

If your application uses gps to track the current location, you’ll want this plugin.

cordova plugin add cordova-plugin-geolocation --save

If your application is using the offline mode plugin, you’ll want to add support for indexedDB to iOS and older devices with this plugin.

cordova plugin add cordova-plugin-indexeddb-async --save

There are many more plugins available at Cordova Plugins.


In order to compile mobile applications with your project inside of it, you will need to build the project and then copy the resulting files into the cordova’s www directory. If you are using one of our templates and followed the steps above to create the cordova project in the cordova directory, you can do this by running the following commands from your application’s root.

gulp build
rm -rf cordova/www
cp -r dist cordova/www

Each time you make a change to your application and want to deploy those changes you will need to re-build and re-copy the source into the cordova www directory.

Finally, run the compilation for each platform you want to support.

cordova build ios
cordova build android

And emulate the apps to preview them.

cordova emulate ios
cordova emulate android

For complete documentation on compiling cordova applications, see Cordova Build

AWS Lambda

There are many cases when you need to perform administrative tasks within your project, but do not wish to expose the permissions necessary for updates to the users of your application. The most common example of this is for Subscription based applications. Let’s suppose that you wish to allow your users to sign up for subscriptions within your application, and based on them paying the fee, their account should be promoted in some way. Either through assigning a role to that user, or by assigning a value within a resource they do not have permissions to update. Since the user is logged into their account when the subscription is made, you need a way to perform an administrative update to the project (give them more access), but cannot expose that API to the user who is logged into the app.

For this example, AWS Lambda provides a very robust way to create a Proxy method which the application uses to perform the validation of the request (like through your payment processor) and then subsequently perform administrative API requests into the project. There is a lot of documents on the web that provide detail on how to configure and utilize AWS Lambda, so below is some example Node.js code that can be placed within your Lambda function which will perform an administrative update to a record based on a user based authenticated request.

Example Lambda Code to Update a User via Admin privileges from a users JWT Token

'use strict';
const https = require('https');

// Enter your project API key here, which will provide AWS Lambda requests
// admin privilages.
let apiKey = '--- YOUR FORM.IO PROJECT API KEY ---';

// The lambda event execution context.
exports.handler = (event, context, callback) => {

    // The user will make a request to Lambda and provide his/her JWT Token
    // We will now use the "current" endpoint within our project to determine the
    // full user object from that token.
    const requestUser = https.request({
        hostname: '',
        path: '/current',
        method: 'GET',
        headers: {
            'x-jwt-token': event.jwtToken
    }, (requestUserResponse) => {
        let user = '';
        requestUserResponse.on('data', (chunk) => user += chunk);
        requestUserResponse.on('end', () => {

            // We now have the full user object. Parse it as a JSON object.
            user = JSON.parse(user);

            // Here is where you could do something to validate the user...
            // Such as, send a request to payment processor to validate payment
            // token, etc.

            // Say that this user is now valid.
   = true;

            // Now perform a PUT reqeust to update the user record as an administrator.
            // We will use the x-token header which utilizes the Project API key to perform
            // the update.
            const updateUser = https.request({
                hostname: '',
                path: '/user/submission/' + user._id,
                method: 'PUT',
                headers: {
                    'x-token': apiKey,
                    'Content-Type' : 'application/json'
            }, (updateUserResponse) => {

                // The user is now updated and valid.
                callback(null, user);
            updateUser.on('error', callback);
    requestUser.on('error', callback);

After you have the Lambda function created, you now just need to hook that up to the AWS API Gateway to create a serverless API proxy into your account.

There are many applications for this capability, but this illustrates an example on how AWS Lambda can be used as an API Proxy into

Remote Middleware

Remote middleware allows binding to the project API and modifying requests from the user in an asynchronous fashion. In this way it is possible to act as express middleware over websockets in real time and reject the request, modify it or move the request to a third party service. This allows you to extend the API platform with your own services in real-time.

Command Line Binding

The easiest way to get started with our Remote Middleware technology is to use our Command Line interface tool to help establish a websocket connection to the form you are interested in binding to. You can download the Command Line Interface by typing the folling within your terminal.

npm install -g formio-cli

Once you have this installed, you will be using the bind method to create the websocket connection between your terminal and the remote API platform. The format for the bind method is as follows.

formio bind [method] [url] [middleware]

Where the following parameters need to be provided.

  • [method] - The HTTP method you wish to bind yourself to. “GET”, “PUT”, “POST”, or “DELETE”
  • [url] - The API endpoint for the form you wish to bind.
  • [middleware] - The Node.js (javascript) file that contains the middleware you wish to execute.

Once executed, the Command Line Interface will ask you for your credentials of the service to verify that you have the appropriate permissions to bind to the desired endpoint.

It should be noted, that if you omit the middleware parameter, that the command line interface will print out the RAW JSON data to the terminal. This can be used to pipe this data into another application. As an example, lets say we wish to bind to our “user” resource form as follows.

formio bind POST

This would then show the following once you created a new User into the resource table.

Custom Remote Middleware

Not only can you bind to an API via command line, but you can also execute a middleware file which can gain direct, real-time access to the requests as they are coming into This can be done by creating a Node.js middleware file that has a similar syntax to Express.js middleware.

For example, let’s suppose we wish to dynamically alter a submission as it is being submitted. A good use case for this is when you wish to alter the emails of your application in a test environment by append “” to the emails in a submission. This can be done creating a JavaScript file that takes the submission data, alters it, and then executes a next method when it is done altering. Here is an example of what this middleware would look like.

This file could then be bound to the Form as follows within the command line.

formio bind POST ./middleware.js

Now when you submit a new submission into that form, this middleware will be executed remotely, and then altered in real-time.

We think it is pretty amazing too.

Node.js Remote Middleware

Remote middleware can also be utilized within a Node.js application using the popular module Primus. We have included a handy wrapper for our binding capabilities within our Service library. You can include this library within your Node.js application using the following.

npm install -g formio-service

Once you have this within your application, you can bind to a form using the following code.

Application Cloning

You can bootstrap any application within GitHub easily with our one line bootstrap command. First find a repository that you wish to bootstrap. You can find some on Formio Github.

Install the formio-cli tool by running this command in the command line.

npm install -g formio-cli

Use the bootstrap command to clone an application. This will both download the sample application to your local machine and set up a formio project with the proper template.

formio bootstrap [GitHub Project]

Once the app is downloaded and set up, run the serve command to do local development.

formio serve [Directory]

Nodejs Library

We have created a nodejs library called formio-service to make it easier to interface directly with <>. You can use it to perform administrative functionality on the <> service.