Overview

These days, it can be hard to promote a web integration. Well, we'd be happy to help you with that. Integrate with Jotform and get your web integration featured to our 25 Million users! Building a Jotform Integration is great way to promote your app. We will add your logo and product name on our Form Builder Integrations Wizard.

integration apps

It's easy. We have great tools that make it very easy to implement an integration. All you need to do is use handle authentication with your integration, use our Question Mapper widget to connect form builds to data fields on your integration, and setup & handle webhook requests sent from Jotform.

We’re here to help, and we'd love to hear your thoughts. Feel free to email us at api@jotform.com. We'd be happy to help you.

Video Demo

Examples

A complete open-source Jotform integration sample could be found on github.

myCRM is a simple web integration written in PHP & MySQL. Feel free to install it on your server to start your development with a working codebase.

Tutorial - Creating Your Integration

This is a step by step tutorial on how to create an integration.

1. Register your integration

Go to Integrations page to begin registering your integration. Selecting the correct platform is essential when creating an integration. When asked to choose your integration platform you will need to select Web Integration from the list, and then select Web Integration from the options that appear below.

2. Choose your integration mode

You will then need to select the mode of your integration. You will have the following choices:

  • Canvas Mode - This mode is fully customizable. All you do is supply Jotform with a Url and you take care of authorization, field matching, and matching form submission data to your users. For more info, see - Canvas integration tutorial.

  • Simple Mode - This mode is not customizable, but Jotform will collect and process authorization, field matching, and submission data for you based on the details you provide them with.

3. Enter your integration settings

The settings that you are asked to enter will be dependant on the the mode you set for your integration.

  • Misc Settings

    • Removal Notification Url (optional) - Do you want Jotform to notify you when a user removes your integration from their form? This can be used for removing settings from your database, removing webhooks, etc. The Url you provide will receive a POST request from Jotform containing the following parameters: formId, username, apiKey.
  • Canvas Mode

    • Canvas Url - The Url that Jotform will serve through an iframe on the integrations wizard. See the tutorial below for more information a setting up your Canvas Page.

  • Simple Mode

    • Authorization
      You will need to authenticate users with you app/service. Jotform will create a authentication form using the details you provide below. Jotform will send a request to the Url you provide to check users authentication. You should return a "SUCCESS" string if users are authenticated.
      • Request Type - The type of request Jotform should send to your authorization Url.

      • Parameters - An array of auth parameters objects. Jotform will use this to create a authentication form for users to fill out.
        E.g [{"name": "username", "label": "Username", "name": "apiKey", "label": Api Key}]

        name: The name of the input
        label: The form label for the input

      • Url - The Url that Jotform will send the user supplied authentication details for you to authenticate users with your integration.



    • Data Fields - An array of data field objects for your integration. Users will need to map their form fields to your supplied data fields. This will allow Jotform to match the form submissions to your data fields and send the matched data to you.

      E.g : [{"value":"First Name","key":"first_name","type":"control_textbox","autoMatch":0},{"value":"Last Name","key":"last_name","type":"control_textbox","autoMatch":0},{"value":"Email","key":"email","type":"control_email","autoMatch":1}]

      For a more detailed explanation please refer to Question Mapper documentation.

    • Data Post Url - The Url where Jotform where will send the matched submission data.

4. Create your canvas (Canvas mode integrations only)

If you are creating a canvas integration, you will need to create a canvas page to display in the Jotform integrations wizard. Please refer to the Canvas integration tutorial below.


5. Check your integration on the Jotform Form Builder

Go to jotform.com. On form builder, click "Integrations" button via the "Setup & Embed" tab on the toolbar. You should see a tab titled My Integrations. Click that tab to see if your integration name and integration image show up on that page.

Now, if you click your integration icon, it will open another modal box. Your canvas URL will be shown within the iFrame. Jotform issues a POST request to your canvas URL with the following parameters:

Tutorial - Creating Your Canvas Integration

If you have chosen a canvas for your integration

1. Set up your canvas Url

Your canvas Url is the page users are shown when they choose to integrate a form with your integration or service. This url will be loaded through an iframe inside in Jotform integrations wizard.

When this happens Jotform instantly issue a POST request to your canvas Url with the following parameters:

  • formId - The id of the current form, for which the integration is set being set up.
  • apiKey - A "full access" apiKey for the current users account. Use this to perform Jotform api requests on behalf of the current user.
  • username - The Jotform username of current user. You may use this to help identify current user.

You should capture these POST parameters for later usage. Here an example:

       <?php
          $formId = $_POST["formId"];
          $username = $_POST["username"];
          $apiKey = $_POST["apiKey"];
       ?>
    

2. Authenticate the user to your integration

Your next step is to authenticate the user of your integration so that you can identify who should receive the data that will be sent by Jotform.

It is up to you how you authenticate the users. You can do it by simply rendering a login dialog box to user, or by giving the user the option to register with your service. Remember, you have to know the integration user id of the user in order to complete integration. In our example integration, we have simple login box to authenticate.


3. Show Question Mapper Widget to map your integration's fields to user's form fields

What your integration is trying to achieve is the population of your backend with the submitted form data received from the Jotform webhook. You have to identify which questions on the form will be connected to which fields within your own integration database.

Let's give you an example: suppose that your integration has a contacts database table having following fields:

  • first_name
  • last_name
  • email
  • location
  • comments

You may initiate Jotform Question Mapper widget with the following code

            //initialize jotform js sdk for integration apps,
            JF.connect({
                apiKey : apiKey,
                formId: formId
            });

            //boot fieldMatcher on given element
            JF.fieldMatch({
                el : document.getElementById("fieldMatcher"),
                targetFields : [
                    {
                        value: "First Name",
                        key : "first_name",
                        type:"control_textbox",
                        autoMatch:true
                    },
                    {
                        value: "Last Name",
                        key  : "last_name",
                        type :"control_textbox",
                        autoMatch:true
                    },
                    {
                        value: "Email",
                        key : "email",
                        type:"control_email",
                        autoMatch:true
                    },
                    {
                        value: "Address",
                        key : "location",
                        type:"control_adress",
                        autoMatch:true
                    },
                    {
                        value: "Comments",
                        key : "comments",
                        type:"control_textbox",
                        autoMatch:true
                    },
                ],
                callback : function(m){
                    //we have matches go step3
                    matches = m;
                    step3();
                }

            });

        

The only catch here is this: the el parameter is the target DOM element where widget is to be rendered. Other than that, complete documentation of Question Mapper can be found on here.

When a user clicks the finish button, you'll receive "matches" on your callback function. Here is a JSON representation of a sample matches javascript object:

            [{
                "key": "first_name",
                "question": {
                    "key": "1",
                    "value": "jotform first name",
                    "type": "control_textbox",
                    "base": {
                        "hint": " ",
                        "labelAlign": "Auto",
                        "name": "jotformFirst",
                        "order": "1",
                        "qid": "1",
                        "readonly": "No",
                        "required": "No",
                        "size": "20",
                        "text": "jotform first name",
                        "type": "control_textbox",
                        "validation": "None"
                    }
                },
                "target": {
                    "value": "First Name",
                    "key": "first_name",
                    "type": "control_textbox",
                    "autoMatch": true
                },
                "qkey": "1"
            }, {
                "key": "last_name",
                "question": {
                    "key": "3",
                    "value": "jotform last name",
                    "type": "control_textbox",
                    "base": {
                        "hint": " ",
                        "labelAlign": "Auto",
                        "name": "jotformLast",
                        "order": "2",
                        "qid": "3",
                        "readonly": "No",
                        "required": "No",
                        "size": "20",
                        "text": "jotform last name",
                        "type": "control_textbox",
                        "validation": "None"
                    }
                },
                "target": {
                    "value": "Last Name",
                    "key": "last_name",
                    "type": "control_textbox",
                    "autoMatch": true
                },
                "qkey": "3"
            }, {
                "key": "email",
                "question": {
                    "key": "4",
                    "value": "jotform email",
                    "type": "control_email",
                    "base": {
                        "confirmation": "No",
                        "confirmationHint": "Confirm Email",
                        "disallowFree": "No",
                        "hint": "ex: myname@example.com",
                        "labelAlign": "Auto",
                        "name": "jotformEmail",
                        "order": "3",
                        "qid": "4",
                        "readonly": "No",
                        "required": "No",
                        "size": "30",
                        "text": "jotform email",
                        "type": "control_email",
                        "validation": "Email"
                    }
                },
                "target": {
                    "value": "Email",
                    "key": "email",
                    "type": "control_email",
                    "autoMatch": true
                },
                "qkey": "4"
            }, {
                "key": "comments",
                "question": {
                    "key": "5",
                    "value": "jotform location",
                    "type": "control_textbox",
                    "base": {
                        "hint": " ",
                        "labelAlign": "Auto",
                        "name": "jotformLocation",
                        "order": "4",
                        "qid": "5",
                        "readonly": "No",
                        "required": "No",
                        "size": "20",
                        "text": "jotform location",
                        "type": "control_textbox",
                        "validation": "None"
                    }
                },
                "target": {
                    "value": "Comments",
                    "key": "comments",
                    "type": "control_textbox",
                    "autoMatch": true
                },
                "qkey": "5"
            }]
        

“Matches” is an array of match objects each representing a map between Jotform form fields and your targetFields.

  • key : key of targetField
  • target : targetField object as you pass to Question Mapper
  • qkey : key of the Jotform form question
  • question : Jotform form question object

So, when you receive a request on your webhook callback url, you'll fetch the matches array and it will create an insert sql statement using it.


4. Store matches on your backend

Now you have received the matches object representing the nature of your integration to Jotform as dictated by the user. You now have to store it so that it can be used in webhooks callback page.

Here is a sample code on how you may store a matches object on a MySQL table:

Here is Javascript code to send matches to backend: (Note: username,myCMUsername and formID are global variables on which you can learn more by looking at the complete canvas url implementation.)

        $.post("save_settings.php",
        {
            matches:JSON.stringify(matches),
            username :myCRMUsername,
            jotUsername : username,
            formId : formId
        },function(resp){
                console.log(resp);
                //call complete to finish this
                JF.complete();
        });
    

Here is the implementation of "save_settings.php" residing at the same directory as canvas url.

        <?php
        //simple php ajax responder for myCRM settings save
        $handle = mysql_connect('YOUR_MYSQL_HOST', "YOUR_MYSQL_USERNAME","YOUR_MYSQL_PASSWORD");
        mysql_select_db("YOUR_MYSQL_DBNAME",$handle);

        $matches = mysql_real_escape_string($_POST["matches"],$handle);
        $formId = mysql_real_escape_string($_POST["formId"],$handle);
        $username = mysql_real_escape_string($_POST["username"],$handle);
        $jot_username = mysql_real_escape_string($_POST["jotUsername"],$handle);

        $query = "insert into settings (username,formId,jot_username,matches) values (
                    '$username',
                    '$formId',
                    '$jot_username',
                    '$matches'
            )";

        $result = mysql_query($query,$handle);
        $output = "OK"; //hope no error occurs here!!!

        mysql_close($handle);
        echo $output;//send username or NOTOK to client

        ?>
    

Remember to replace all the mysql connection parameters with the ones that you use. A link to the mysql table sql dump can be found at the bottom of this page, yet the settings table’s structure is pretty obvious.

5. Create a Webhook

When a submission is made to user's form, the data will be sent to your backend using webhooks. To create a webhook, you must supply a callback url to Jotform API, then every time a form receives a submission, your webhook callback url will receive an HTTP POST request from Jotform servers.

You may simply create a webhook using following javascript code:

        //create webhook
        JF.createFormWebhook(formId,webhookUrl,function(){

        },function(){
            alert("error creating webhook");
        });
    

6. Call JF.complete()

So far, you authenticated the user, mapped your fields to a Jotform form questions using question mapper, stored these matches and created a webhook. Now you have to notify Jotform form builder about the status of the process, and tell it to notify the user regarding the completion of the integration process and close the integration modal box. Just use following code and your integration is now integrated with Jotform!

        JF.complete();
    

7. Handle webhook callbacks

Here is the complete source code of myCRM webhook callback implementation, written in PHP. It can also be found in the repo

        <?php

        //fetch POST parameters
        $formId = $_POST["formID"];
        $submissionID = $_POST["submissionID"];
        $rawRequest = $_POST["rawRequest"];

        //unescape json encoded rawRequest string
        $escapedRawRequest = unescapeJSON($rawRequest);

        $req = json_decode($escapedRawRequest,true);

        //fetch matches and username from formId inside settings table
        //establish mysql connection
        $handle = mysql_connect('YOUR_MYSQL_HOST', "YOUR_MYSQL_USERNAME","YOUR_MYSQL_PASSWORD");
        mysql_select_db("YOUR_MYSQL_DBNAME",$handle);

        $formId = mysql_real_escape_string($formId,$handle);
        $result = mysql_query("select * from settings where formId = '$formId'",$handle);
        if(mysql_num_rows($result) !== 0){
            //found an entry in settings table belonging to $formId
            $fetch = mysql_fetch_assoc($result);
            $matches = str_replace('\\"', '"', $fetch["matches"]);
            $matches = json_decode($matches);

            $insertValues = array(); //lets populate insert values using matches and rawRequest
            $username = $fetch["username"];

            //find userid
            $sq = "select id from user where username = '".mysql_real_escape_string($username,$handle)."'";
            $sr = mysql_query($sq,$handle);
            $sf = mysql_fetch_assoc($sr);
            $user_id = $sf["id"];

            foreach( $req as $key => $value){
                if(is_array($value) ){
                    foreach($value as $sk => $sv){
                        $search_key = explode("_",$key);
                        $search_key = $search_key[0];
                        $finded = searchFromMatches($matches,$search_key."_".$sk,"true");
                        if($finded !== false){
                            $insertValues[$finded->key] = $sv;
                        }
                    }
                    //handle subfields
                }else{
                    echo "search started => $key \n";
                    $finded = searchFromMatches($matches,$key,"false");
                    if($finded !== false){
                        $insertValues[$finded->key] = $value;
                    }
                }
            }
            //set userid
            $insertValues["user_id"] = $user_id;

            //now we have to insert $insertValues array
            $query = "insert into contacts";
            $keys = array();
            $values = array();

            foreach($insertValues as $key => $value){
                $keys[]=$key;
                $values[]=mysql_real_escape_string($value,$handle);
            }
            //build insert query
            $query = $query." (`".implode("`,`",$keys)."`) values ('".implode("','",$values)."')";
            mysql_query($query,$handle);
            //we are done, record inserted

        }else{
            echo "no integration settings detected";
        }


        //helper functions
        function unescapeJSON($str){
            return str_replace("\\'","'" ,str_replace('\\"', '"', $str));
        }

        function searchFromMatches($matches,$key,$sss){
            if($sss === "false"){
                $key = explode("_", $key);
            }else{
                $key = array($key);
            }
            $key = str_replace("q", "", $key[0]);
            foreach($matches as $match){
                if($match->question->key == $key){
                    return $match->target;
                }
            }
            return false;
        }
        ?>
    
Top