REST API v1 Guide

Introduction

The REST API v1, formerly called the Web API, allows developers to create, read, update and delete forms, entries and results over HTTP loosely following REST-style principles.

The URI defines the resource and the HTTP method defines the operation.

  • Use the GET HTTP method to read data
  • Use the POST HTTP method to create/add data
  • Use the PUT HTTP method to update data
  • Use the DELETE HTTP method to delete data

The base URI of the Web API is “gravityformsapi”. So the URL would be, for example:

http://mydomain.com/gravityformsapi

or, alternatively, if the WordPress installation is in a sub-directory:

http://mydomain.com/wordpress/gravityformsapi/

The resources are defined in the URL after the base, like this:

http://mydomain.com/gravityformsapi/forms

http://mydomain.com/gravityformsapi/entries

Keys, or object IDs are sent in the next part of the URI, like this:

http://mydomain.com/gravityformsapi/forms/1

http://mydomain.com/gravityformsapi/entries/543

Some resources also support sub-resources, for example:

http://mydomain.com/gravityformsapi/forms/1/results

http://mydomain.com/gravityformsapi/forms/1/entries

TIP:
Most of the endpoints are simply wrappers for their GFAPI counterparts. So if you have trouble getting the REST API v1 to work it can helpful to debug using the PHP equivalent.

Requirements

The REST API v1 requires “pretty” permalinks to be enabled. Please ensure that the permalink setting is NOT set to the default (http://mydomain.com/?p=123) before trying to use the REST API v1. Any setting other than the default will be fine.

The REST API v1 is activated on the API settings tab. You can leave the default keys or generate new ones.

Security

In addition to the security measures enforced by the REST API v1, it’s strongly advisable to implement SSL for the WordPress site (beyond the scope of this API).

Authentication

There are two types of authentication:

Are you a plugin/theme running on the site? Use WordPress cookie authentication.
Are you a desktop/web/mobile client accessing the site externally? Use signatures.

All endpoints require authentication with the exception of the POST forms/[ID]/submissions end point.

WordPress Cookie Authentication

Cookie authentication is the basic authentication method included with WordPress. When users log in, this sets up the cookies, so plugin and theme developers need only to have a logged-in user.

However, the Gravity Forms REST API v1 uses nonces to avoid CSRF issues. This prevents other sites from forcing you to perform actions without explicitly intending to do so.

The REST API v1 uses nonces with the action set to gf_api. These are then be passed to the API with each request via the _gf_json_nonce parameter in the URL.

Authentication for External applications

All requests from external applications are authenticated by checking an expiring signature. This is similar to the approach used by Amazon to secure access to their S3 Storage API. Once authenticated, standard WordPress and Gravity Forms role-based authorization is used to ensure that the API request is allowed to be fulfilled.

Each request at a minimum must include the following 3 query parameters:

  • api_key – The public API key defined on the settings page e.g. “1234”
  • expires – Expiration date for the request expressed as a UNIX timestamp in seconds e.g. 1369749344
  • signature – A URL-encoded, base64 HMAC-SHA1 hash of a colon separated string following this structure:
    {api_key}:{http method}:{route}:{expires}
    e.g. 1234:GET:forms/1/entries:1369749344
    The signature for this request using the private key of “abcd” is uJEnk0EoQ4d3iinjFMBrBzZfH9w%3D

Complete example request:

GET
http://mydomain.com/gravityformsapi/forms/25?api_key=1234&signature=PueNOtbfUe%2BMfClAOi2lfq%2BHLyo%3D&expires=1369749344

Sample code for generating signatures:

PHP

<?php
function calculate_signature($string, $private_key) {
    $hash = hash_hmac("sha1", $string, $private_key, true);
    $sig = rawurlencode(base64_encode($hash));
    return $sig;
}

$api_key = "1234";
$private_key = "abcd";
$method  = "GET";
$route    = "forms/1/entries";
$expires = strtotime("+60 mins");
$string_to_sign = sprintf("%s:%s:%s:%s", $api_key, $method, $route, $expires);
$sig = calculate_signature($string_to_sign, $private_key);
var_dump($sig);
?>

JavaScript
WARNING: This sample JavaScript is not secure and it’s not intended to be used on production sites. Never send your private key to the browser. Consider using WordPress cookie authentication instead.

<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/hmac-sha1.js"></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/enc-base64-min.js"></script>
<script type="text/javascript">

    function CalculateSig(stringToSign, privateKey){
        var hash = CryptoJS.HmacSHA1(stringToSign, privateKey);
        var base64 = hash.toString(CryptoJS.enc.Base64);
        return encodeURIComponent(base64);
    }

    var d = new Date,
         expiration = 3600 // 1 hour,
         unixtime = parseInt(d.getTime() / 1000),
         future_unixtime = unixtime + expiration,
         publicKey = "1234",
         privateKey = "abcd",
         method = "GET",
         route = "forms/1/entries";

    stringToSign = publicKey + ":" + method + ":" + route + ":" + future_unixtime;
    sig = CalculateSig(stringToSign, privateKey);
    console.log(sig);
</script>

C#

using System;
using System.Web;
using System.Security.Cryptography;
using System.Text;

namespace GravityForms
{
    public class Sample
    {
        public static GenerateSignature()
        {
            string publicKey = "1234";
            string privateKey = "abcd";
            string method = "GET";
            string route = "forms/1/entries";
            string expires = Security.UtcTimestamp(new TimeSpan(0,1,0));
            string stringToSign = string.Format("{0}:{1}:{2}:{3}", publicKey, method, route, expires);



            var sig = Security.Sign(stringToSign, privateKey);
            Console.WriteLine(sig);
        }
    }

    public class Security
    {

        public static string UrlEncodeTo64(byte[] bytesToEncode)
        {
            string returnValue
                = System.Convert.ToBase64String(bytesToEncode);

            return HttpUtility.UrlEncode(returnValue);
        }

        public static string Sign(string value, string key)
        {
            using (var hmac = new HMACSHA1(Encoding.ASCII.GetBytes(key)))
            {
                return UrlEncodeTo64(hmac.ComputeHash(Encoding.ASCII.GetBytes(value)));
            }
        }

        public static int UtcTimestamp( TimeSpan timeSpanToAdd)
        {
            TimeSpan ts = (DateTime.UtcNow.Add(timeSpanToAdd) - new DateTime(1970,1,1,0,0,0));
            int expires_int =  (int) ts.TotalSeconds;
            return expires_int;
        }
    }
}

Authorization

The REST API v1 adds an additional layer of security by executing the request on behalf of the user account defined in the account impersonation setting on the settings tab. Roles and capabilities for role-based authorization can be configured using the Members plugin.

The number of users available on the settings page is set to a maximum of 200. This can be changed using the gform_webapi_get_users_settings_page filter.

Response

The response body will always be a JSON object containing a status code and the result of the request. The HTTP status code in the header will always be 200 regardless of the result so it’s important to check for the status code in the response body to determine the success or failure of the request.

So, for example, if a non-existent form is requested, the raw response body would be the following:

{
    "status": 404,
    "response": "Not found"
}

A successful request for a form would look like this:

{
  "status": 200,
  "response": {
    "title": "My Form",
    "description": "This is my form",
    ... snip ...
    }
}

TIP: successful requests will return a status of 200, 201 or 202. Anything above 202 signifies an error. See the section below on status codes for further details.

Status Codes

Although the HTTP status code in the response header will always be 200, the status code in the response body will follow the standard HTTP status code definitions:

  • Successful requests will generate either a 200 (OK) or 201 (resource created) status code.

  • Accepted but unfinished requests will generate a 202 (accepted) status code.

  • Illegal or illogical requests, will result in a 400 (bad request) status code.

  • Unauthenticated or unauthorized requests will receive the 401 (not authorized) status code.

  • Requests for non-existent resources will receive a 404 (not found) status code.

  • Server errors will generate a 500 (server error) status code.

  • Unsupported requests will receive the 501 (Not implemented) status code.

Errors

When the request is not successful, the status code will be greater than 202. When appropriate, and when available, additional information about the error will be returned in the response element in the following format:

  • code: a code identifying further details about the error.
  • message: a description of the error
  • data: additional data pertaining to the failure. e.g. the error message generated by MySQL Server.

Example of an error message after trying to update an entry without a form ID:

{
  "status": 400,
  "response": {
    "code": "empty_form_id",
    "message": "The form ID must be specified"
    }
}

Example of an error when trying to update an array of entries but one of the entries could not be found:

{
  "status": 404,
  "response": {
    "code": "not_found",
    "message": "Entry with ID 414 not found",
    "data": 414
    }
}

File extension support

For the sake of clarity, forward compatibility and hook-based extensibility, a file extension is supported as part of the url. Currently .json is the only supported extension. This means that both of the following GET requests receive identical responses (the entry object):

http://mydomain.com/wordpress/gravityformsapi/forms/14/entries.json
http://mydomain.com/wordpress/gravityformsapi/forms/14/entries

Forms

For more detailed examples of how to work with forms, go to REST API v1 Examples.

GET /forms

Returns a list of all ACTIVE forms along with its entry count.

  • URI: /gravityformsapi/forms
  • Capability: gravityforms_edit_forms
  • Output: JSON string with the id, title, entry count for each form:
    {
        "1": {
            "id": "1",
            "title": "test form",
            "entries": "15"
        },
        "2": {
            "id": "2",
            "title": "test form 2",
            "entries": "26"
        }
    }
    
  • Example:
    The example below retrieves all ACTIVE forms:

PHP

//set API keys
$api_key = 'your_api_key';
$private_key = 'your_private_key';

//set route
$route = 'forms';

//creating request URL
$expires = strtotime( '+60 mins' );
$string_to_sign = sprintf( '%s:%s:%s:%s', $api_key, 'GET', $route, $expires );
$sig = calculate_signature( $string_to_sign, $private_key );
$url = 'http://localhost/wp/gravityformsapi/' . $route . '?api_key=' . $api_key . '&signature=' . $sig . '&expires=' . $expires;

//retrieve data
$response = wp_remote_request( urlencode( $url ), array( 'method' => 'GET' ) );
if ( wp_remote_retrieve_response_code( $response ) != 200 || ( empty( wp_remote_retrieve_body( $response ) ) ) ){
	//http request failed
	die( 'There was an error attempting to access the API.' );
}

//result is in the response "body" and is json encoded.
$body = json_decode( wp_remote_retrieve_body( $response ), true );

if( $body['status'] > 202 ){
	die( "Could not retrieve forms." );
}

//forms retrieved successfully
$forms = $body['response'];

//To access each form, loop through the $forms array.
foreach ( $forms as $form ){
	$form_id     = $form['id'];
	$form_title  = $form['title'];
	$entry_count = $form['entries'];
}

function calculate_signature( $string, $private_key ) {
	$hash = hash_hmac( 'sha1', $string, $private_key, true );
	$sig = rawurlencode( base64_encode( $hash ) );
	return $sig;
}

JavaScript
WARNING: This sample JavaScript is not secure and it’s not intended to be used on production sites. Never send your private key to the browser. Consider using WordPress cookie authentication instead.

<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/hmac-sha1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/enc-base64-min.js"></script>
<script type="text/javascript">
function CalculateSig(stringToSign, privateKey){
    //calculate the signature needed for authentication
    var hash = CryptoJS.HmacSHA1(stringToSign, privateKey);
    var base64 = hash.toString(CryptoJS.enc.Base64);
    return encodeURIComponent(base64);
}

//set variables
var d = new Date;
var expiration = 3600; // 1 hour,
var unixtime = parseInt(d.getTime() / 1000);
var future_unixtime = unixtime + expiration;
var publicKey = "your_public_key";
var privateKey = "your_private_key";
var method = "GET";
var route = "forms";

stringToSign = publicKey + ":" + method + ":" + route + ":" + future_unixtime;
sig = CalculateSig(stringToSign, privateKey);
var url = 'http://localhost/wp.dev/gravityformsapi/' + route + '?api_key=' + publicKey + '&signature=' + sig + '&expires=' + future_unixtime;

$.get(url, function(data, textStatus)
{
    //get the data from the api
    if ( data.status != 200 || ( typeof( data ) != 'object' ) ) {
        //http request failed
        document.write( 'There was an error attempting to access the API - ' + data.status + ': ' + data.response );
        return;
    }
    forms         = data.response;
    document.write('<p>Results</p>');
    document.write('<table border="1"><th>Form ID</th><th>Form Title</th><th>Entry Count</th>');
    for (var form in forms) {
        document.write('<tr><td>' + forms[form]['id'] + '</td><td>' + forms[form]['title'] + '</td><td>' + forms[form]['entries'] + '</td></tr>');
    }
    document.write("</table>");
});
</script>

Sample JSON output from the code above:

{"status":200,"response":{"20":{"id":"20","title":"Captcha 2","entries":"35"},"15":{"id":"15","title":"Credit Card Form","entries":"24"},"5":{"id":"5","title":"Custom Contact Form","entries":"0"},"24":{"id":"24","title":"Drop Down Test Alert Conditional Logic","entries":"0"},"1":{"id":"1","title":"Freshbooks","entries":"28"},"27":{"id":"27","title":"List Field","entries":"1"},"11":{"id":"11","title":"PayPal Standard","entries":"8"},"12":{"id":"12","title":"PayPal Standard - No Other Add-Ons","entries":"4"},"13":{"id":"13","title":"PayPal Standard With Zapier Not Delayed","entries":"1"},"18":{"id":"18","title":"Post Body Test with Text Editor","entries":"2"},"14":{"id":"14","title":"Products","entries":"39"},"19":{"id":"19","title":"Recaptcha","entries":"5"},"25":{"id":"25","title":"reCaptcha Multi-Page Test Page 1","entries":"2"},"26":{"id":"26","title":"reCaptcha Test Page 2","entries":"2"},"28":{"id":"28","title":"Test Form","entries":"21"},"21":{"id":"21","title":"Test reCaptcha 2","entries":"0"},"16":{"id":"16","title":"Textarea Test With Editor","entries":"2"},"2":{"id":"2","title":"Untitled Form","entries":"0"},"3":{"id":"3","title":"User Signup","entries":"1"},"4":{"id":"4","title":"User Signup - Update","entries":"1"},"29":{"id":"29","title":"_Test Recaptcha Secure Token","entries":"6"}}}

GET /forms/[Form IDs]

Returns a Form object. Multiple forms may be requested by separating the IDs by semicolons.

  • URI: /gravityformsapi/forms/1 or /gravityformsapi/forms/1;3;6
  • Capability: gravityforms_edit_forms
  • Output: A JSON string containing the form or forms
  • Notes: If a form does not exist for a form id provided, false is returned for that form. The entry count is not included.
  • Example:
    The example below retrieves the forms with ids 1000, 1, 14, 28, 29. Form id 1000 does not exist so false is returned for that form.

PHP

//set API keys
$api_key = 'your_api_key';
$private_key = 'your_private_key';

//set route
$route = 'forms/1000;1;14;28;29';

//creating request URL
$expires = strtotime( '+60 mins' );
$string_to_sign = sprintf( '%s:%s:%s:%s', $api_key, 'GET', $route, $expires );
$sig = calculate_signature( $string_to_sign, $private_key );
$url = 'http://localhost/wp/gravityformsapi/' . $route . '?api_key=' . $api_key . '&signature=' . $sig . '&expires=' . $expires;

//retrieve data
$response = wp_remote_request( urlencode( $url ), array( 'method' => 'GET' ) );
if ( wp_remote_retrieve_response_code( $response ) != 200 || ( empty( wp_remote_retrieve_body( $response ) ) ) ){
	//http request failed
	die( 'There was an error attempting to access the API.' );
}

//result is in the response "body" and is json encoded.
$body = json_decode( wp_remote_retrieve_body( $response ), true );

if( $body['status'] > 202 ){
	die( "Could not retrieve forms." );
}

//forms retrieved successfully
$forms = $body['response'];

//To access each form, loop through the $forms array.
foreach ( $forms as $form ){
     $form_id     = $form['id'];
     $form_title  = $form['title'];

     $fields = $form['fields'];
     foreach ( $fields as $field ){
          $field_id = $field['id'];
          $field_label = $field['label'];
     }
}

function calculate_signature( $string, $private_key ) {
	$hash = hash_hmac( 'sha1', $string, $private_key, true );
	$sig = rawurlencode( base64_encode( $hash ) );
	return $sig;
}

JavaScript
WARNING: This sample JavaScript is not secure and it’s not intended to be used on production sites. Never send your private key to the browser. Consider using WordPress cookie authentication instead.

<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/hmac-sha1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/enc-base64-min.js"></script>
<script type="text/javascript">
function CalculateSig(stringToSign, privateKey){
    //calculate the signature needed for authentication
    var hash = CryptoJS.HmacSHA1(stringToSign, privateKey);
    var base64 = hash.toString(CryptoJS.enc.Base64);
    return encodeURIComponent(base64);
}

//set variables
var d = new Date;
var expiration = 3600; // 1 hour,
var unixtime = parseInt(d.getTime() / 1000);
var future_unixtime = unixtime + expiration;
var publicKey = "your_public_key";
var privateKey = "your_private_key";
var method = "GET";
var route = "forms/1000;1;14;28;29";

stringToSign = publicKey + ":" + method + ":" + route + ":" + future_unixtime;
sig = CalculateSig(stringToSign, privateKey);
var url = 'http://localhost/wp.dev/gravityformsapi/' + route + '?api_key=' + publicKey + '&signature=' + sig + '&expires=' + future_unixtime;

$.get(url, function(data, textStatus)
{
	//get the data from the api
	if ( data.status != 200 || ( typeof( data ) != 'object' ) ) {
		//http request failed
		document.write( 'There was an error attempting to access the API - ' + data.status + ': ' + data.response );
		return;
	}
	forms = data.response;
	if ( forms ){
		//loop through form ids returned
		for (var id in forms){
			//if a form is not found, false is returned
			form = forms[id]; //get single form object using id
			form_id = form['id'];
			form_title = form['title'];

			fields = form['fields'];
			field_count=fields['length'];
			if ( fields ){
				for ( var i=0;i<field_count;i++ ){
					field_id = fields[i]['id'];
					field_label = fields[i]['label'];
					field_type = fields[i]['type'];
				}
			}
		}
	}
});
</script>

Sample JSON output from the code above:

{"status":200,"response":{"1000":false,"28":{"title":"Test Form","description":"","labelPlacement":"top_label","descriptionPlacement":"below","button":{"type":"text","text":"Submit","imageUrl":""},"fields":[{"type":"name","id":1,"label":"Name","adminLabel":"","isRequired":false,"size":"medium","errorMessage":"","nameFormat":"advanced","inputs":[{"id":"1.2","label":"Prefix","name":"","choices":[{"text":"Mr.","value":"Mr.","isSelected":false,"price":""},{"text":"Mrs.","value":"Mrs.","isSelected":false,"price":""},{"text":"Miss","value":"Miss","isSelected":false,"price":""},{"text":"Ms.","value":"Ms.","isSelected":false,"price":""},{"text":"Dr.","value":"Dr.","isSelected":false,"price":""},{"text":"Prof.","value":"Prof.","isSelected":false,"price":""},{"text":"Rev.","value":"Rev.","isSelected":false,"price":""}],"isHidden":true,"inputType":"radio"},{"id":"1.3","label":"First","name":""},{"id":"1.4","label":"Middle","name":"","isHidden":true},{"id":"1.6","label":"Last","name":""},{"id":"1.8","label":"Suffix","name":"","isHidden":true}],"formId":28,"pageNumber":1,"description":"","allowsPrepopulate":false,"inputMask":false,"inputMaskValue":"","inputType":"","labelPlacement":"","descriptionPlacement":"","subLabelPlacement":"","placeholder":"","cssClass":"","inputName":"","adminOnly":false,"noDuplicates":false,"defaultValue":"","choices":"","conditionalLogic":"","displayOnly":""},{"type":"text","id":2,"label":"Testing","adminLabel":"","isRequired":false,"size":"medium","errorMessage":"","inputs":null,"formId":28,"pageNumber":1,"description":"","allowsPrepopulate":false,"inputMask":false,"inputMaskValue":"","inputType":"","labelPlacement":"","descriptionPlacement":"","subLabelPlacement":"","placeholder":"","cssClass":"","inputName":"","adminOnly":false,"noDuplicates":false,"defaultValue":"","choices":"","conditionalLogic":"","displayOnly":"","multipleFiles":false,"maxFiles":"","calculationFormula":"","calculationRounding":"","enableCalculation":"","disableQuantity":false,"displayAllCategories":false},{"type":"text","id":3,"label":"Text 2","adminLabel":"","isRequired":false,"size":"medium","errorMessage":"","inputs":null,"labelPlacement":"","descriptionPlacement":"","subLabelPlacement":"","placeholder":"","multipleFiles":false,"maxFiles":"","calculationFormula":"","calculationRounding":"","enableCalculation":"","disableQuantity":false,"displayAllCategories":false,"inputMask":false,"inputMaskValue":"","allowsPrepopulate":false,"formId":28,"pageNumber":1,"description":"","inputType":"","cssClass":"","inputName":"","adminOnly":false,"noDuplicates":false,"defaultValue":"","choices":"","conditionalLogic":""}],"version":"1.9.10.12","id":28,"useCurrentUserAsAuthor":true,"postContentTemplateEnabled":false,"postTitleTemplateEnabled":false,"postTitleTemplate":"","postContentTemplate":"","lastPageButton":null,"pagination":null,"firstPageCssClass":null,"notifications":{"557b09f4495a0":{"id":"557b09f4495a0","to":"{admin_email}","name":"Admin Notification","event":"form_submission","toType":"email","subject":"New submission from {form_title}","message":"{all_fields}"}},"confirmations":{"557b09f457c1b":{"id":"557b09f457c1b","name":"Default Confirmation","isDefault":true,"type":"message","message":"Thanks for contacting us! We will get in touch with you shortly.","url":"","pageId":"","queryString":""}},"is_active":"1","date_created":"2015-06-12 16:33:56","is_trash":"0"}}}

POST /forms

Creates new forms using the given form objects

  • URI: /gravityformsapi/forms
  • Capability: gravityforms_create_forms
  • Input: An array of valid form objects to create. If the ID of the form is included in the form object, then it will be ignored.
  • Output: A JSON string containing an array of Form IDs, one for each form created, in the order in which the forms were processed.
  • Potential Errors:
    If the forms object is not an array, an ‘invalid’ error will be output:

    {"status":400,"response":{"code":"invalid","message":"Invalid form objects"}}

    If the form title is not provided, a ‘missing_title’ error will be output:

    {"status":400,"response":{"code":"missing_title","message":"The form title is missing"}}

    If there is a problem inserting the form in the database, the following message is displayed, along with the applicable SQL error, if one exists:

    {"status":error code,"response":{"code":"insert_form_error","message":"There was a problem while inserting the form","data":"sql statement"}
  • Example:

PHP

//set API keys
$api_key = 'your_api_key';
$private_key = 'your_private_key';

//set route
$route = 'forms';

//creating request URL
$expires = strtotime( '+60 mins' );
$string_to_sign = sprintf( '%s:%s:%s:%s', $api_key, 'POST', $route, $expires );
$sig = calculate_signature( $string_to_sign, $private_key );
$url = 'http://localhost/wp/gravityformsapi/' . $route . '?api_key=' . $api_key . '&signature=' . $sig . '&expires=' . $expires;

$forms = array(
	   array(
	     'title'	      => 'API Generated 10',
	     'description'    => 'This is the description for the form generated by the API',
	     'labelPlacement' => 'top_label',
	     'button'	      => array(
				   'type' => 'text'
	     ),
	    'confirmations'   => array(
				   array(
					'id' => 0,
					'name' => 'Default Confirmation',
					'type' => 'message',
					'message' => 'Thanks for contacting us! We will get in touch with you shortly.',
					'isDefault' => true,
				   ),
             ),
	    'fields'	      => array(
				   array(
					'id' => '1',
					'label' => 'My Text',
					'type'	=> 'text'
				   )
            ,
	  ),
	);

//json encode array
$form_json = json_encode( $forms );

//retrieve data
$response = wp_remote_request( urlencode( $url ), array( 'method' => 'POST', 'body' => $form_json ) );
if ( wp_remote_retrieve_response_code( $response ) != 200 || ( empty( wp_remote_retrieve_body( $response ) ) ) ){
	//http request failed
	die( 'There was an error attempting to access the API.' );
}

//result is in the response "body" and is json encoded.
$body = json_decode( wp_remote_retrieve_body( $response ), true );

if( $body['status'] > 202 ){
	$error = $body['response'];
	//form insert failed, get error information
	$error_code 	= $error['code'];
	$error_message 	= $error['message'];
	$error_data 	= isset( $error['data'] ) ? $error['data'] : '';
	$status 	= "Code: {$error_code}. Message: {$error_message}. Data: {$error_data}.";
	die( "Could not post forms. {$status}" );
}

$form_ids = $body['response'];
$form_ids_created = 'The following form ids were created:</br>';
foreach ( $form_ids as $form_id ){
	$form_ids_created .= $form_id . '</br>';
}

function calculate_signature( $string, $private_key ) {
	$hash = hash_hmac( 'sha1', $string, $private_key, true );
	$sig = rawurlencode( base64_encode( $hash ) );
	return $sig;
}

JavaScript
WARNING: This sample JavaScript is not secure and it’s not intended to be used on production sites. Never send your private key to the browser. Consider using WordPress cookie authentication instead.

<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/hmac-sha1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/enc-base64-min.js"></script>
<script type="text/javascript">
function CalculateSig(stringToSign, privateKey){
    //calculate the signature needed for authentication
    var hash = CryptoJS.HmacSHA1(stringToSign, privateKey);
    var base64 = hash.toString(CryptoJS.enc.Base64);
    return encodeURIComponent(base64);
}

//set variables
var d = new Date;
var expiration = 3600; // 1 hour,
var unixtime = parseInt(d.getTime() / 1000);
var future_unixtime = unixtime + expiration;
var publicKey = "your_public_key";
var privateKey = "your_private_key";
var method = "POST";
var route = "forms";

stringToSign = publicKey + ":" + method + ":" + route + ":" + future_unixtime;
sig = CalculateSig(stringToSign, privateKey);
var url = 'http://localhost/wp.dev/gravityformsapi/' + route + '?api_key=' + publicKey + '&signature=' + sig + '&expires=' + future_unixtime;

var form = {
    title           : 'API Generated Form',
    description     : 'This is the description for the form generated by the API',
    labelPlacement  : 'top_label',
    button          : {type : 'text'},
    confirmations   : [
            {id : 0, name : 'Default Confirmation', type : 'message', message : 'Thanks for contacting us! We will get in touch with you shortly.', isDefault : true},
            {id : 1, name : 'Confirmation 2', type : 'message', message : 'Thanks for contacting us! We will get in touch with you shortly.', isDefault : false}
    ],
    fields      : [
            {id : '1', label : 'My Text', type : 'text'},
            {id : '2', label : 'More Text', type : 'text'}
    ]
};
var form_array = [];
form_array[0] = form;

form_json = JSON.stringify(form_array);
$.post(url, form_json, function(data){
        console.log(data.response);
});
</script>

Sample JSON output for two forms inserted.

{"status":201,"response":[47,48]}

PUT /forms/[Form ID]

Updates the form with a given ID, or if an ID is not provided in the route, updates the form(s) using the provided id(s) in the form array.

NOTE: To perform an update, the form object for the form being updated needs to first be retrieved because the entire Form Object must be sent to the API. If the entire form object is not sent, fields not included will be removed, along with other information.

  • URI: /gravityformsapi/forms/[Form ID] or /gravityformsapi/forms
  • Capability: gravityforms_edit_forms
  • Input: A JSON string representation of the form object(s). If the ID of the form is included in the form object then it will be overwritten with the form ID supplied in the request URI (if there is one).
  • Output: A localized message describing the result: “Form(s) updated successfully”
  • Potential Errors:
    If the form object is not an array, an ‘invalid’ error will be output:

    {"status":400,"response":{"code":"invalid","message":"Invalid form object"}}

    If the form id is not provided in the route and not provided in the individual form array, a ‘missing_form_id’ error will be output:

    {"status":400,"response":{"code":"missing_form_id","message":"Missing form id"}}

    If the form id provided cannot be found in the database, a ‘not_found’ error will be output:

    {"status":404,"response":{"code":"not_found","message":"Form not found"}}

    If there is a problem updating the form in the database, the following message is displayed, along with the applicable SQL error, if one exists:

    {"status":error code,"response":{"code":"error_updating_form","message":"Error updating form","data":"sql statement"}

    If there is a problem updating a confirmation in the database, the following message is displayed, along with the applicable SQL error, if one exists:

    {"status":error code,"response":{"code":"error_updating_confirmations","message":"Error updating form confirmations","data":"sql statement"}

    If there is a problem updating a notification in the database, the following message is displayed, along with the applicable SQL error, if one exists:

    {"status":error code,"response":{"code":"error_updating_notifications","message":"Error updating form notifications","data":"sql statement"}

    If there is a problem updating the form title or the form’s active status in the database, the following message is displayed, along with the applicable SQL error, if one exists:

    {"status":error code,"response":{"code":"error_updating_title","message":"Error updating title","data":"sql statement"}
  • Example:
    The example below updates forms with the ids 83,84:

PHP

//set API keys
$api_key = 'your_api_key';
$private_key = 'your_private_key';

//set route to retrieve forms that will be updated
$route          = 'forms/84;83';
$expires        = strtotime( '+60 mins' );
$string_to_sign = sprintf( '%s:%s:%s:%s', $api_key, 'GET', $route, $expires );
$sig            = self::calculate_signature( $string_to_sign, $private_key );
$url            = 'http://localhost/wp.dev/gravityformsapi/' . $route . '?api_key=' . $api_key . '&signature=' . $sig . '&expires=' . $expires;

//retrieve data
$response = wp_remote_request( $url, array( 'method' => 'GET' ) );
if ( wp_remote_retrieve_response_code( $response ) != 200 || ( empty( wp_remote_retrieve_body( $response ) ) ) ) {
	//http request failed
	die( 'There was an error attempting to access the API.' );
}

//result is in the response "body" and is json encoded.
$body = json_decode( wp_remote_retrieve_body( $response ), true );

if ( $body['status'] > 202 ) {
	die( "Could not retrieve forms." );
}

//forms retrieved successfully
$forms = $body['response'];

//set route for updating
$route = 'forms';

//creating request URL
$expires        = strtotime( '+60 mins' );
$string_to_sign = sprintf( '%s:%s:%s:%s', $api_key, 'PUT', $route, $expires );
$sig            = self::calculate_signature( $string_to_sign, $private_key );
$url            = 'http://localhost/wp.dev/gravityformsapi/' . $route . '?api_key=' . $api_key . '&signature=' . $sig . '&expires=' . $expires;

foreach ( $forms as &$form ) {
	//loop through forms and update data
	//use the & so form object is updated in loop
	if ( $form['id'] == '83' ){
		//update the title for the form, no other changes
		$form['title'] = 'Title Updated by API';

		//update confirmations
		$form['confirmations'] = array(
				array(
					'id'   => 0,
					'name' => 'Default Confirmation',
					'type' => 'message',
					'message' => 'Thanks for contacting us! We will get in touch with you shortlyXXX.',
					'isDefault' => true,
				),
		);
		break;
	}

	if ( $form['id'] == '84' ) {
		foreach ( $form['fields'] as &$field ) {
			//use the & so field object is updated in loop
			//update the field label and drop down choices, leave other fields alone
			if ( $field['id'] == '2' ) {
				$field['label']   = 'Updated from API';
				$field['choices'] = array(
					array(
						'text'  => 'Bulk Item Pickup',
						'value' => '3B6D4BD9B6FF',
					),
					array(
						'text'  => 'General Repair',
						'value' => 'E26618F9E10A'
					)
				);
			}
		}
	}
}

//json encode array
$form_json = json_encode( $forms );

//retrieve data
$response = wp_remote_request( urlencode( $url ), array( 'method' => 'PUT', 'body' => $form_json ) );
if ( wp_remote_retrieve_response_code( $response ) != 200 || ( empty( wp_remote_retrieve_body( $response ) ) ) ){
	//http request failed
	die( 'There was an error attempting to access the API.' );
}

//result is in the response "body" and is json encoded.
$body = json_decode( wp_remote_retrieve_body( $response ), true );

if( $body['status'] > 202 ){
	$error = $body['response'];

	//form insert failed, get error information
	$error_code 	= $error['code'];
	$error_message 	= $error['message'];
	$error_data 	= isset( $error['data'] ) ? $error['data'] : '';
	$status 	    = "Code: {$error_code}. Message: {$error_message}. Data: {$error_data}.";
	die( "Could not update forms. {$status}" );
}

JavaScript
WARNING: This sample JavaScript is not secure and it’s not intended to be used on production sites. Never send your private key to the browser. Consider using WordPress cookie authentication instead.

<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/hmac-sha1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/enc-base64-min.js"></script>
<script type="text/javascript">
function CalculateSig(stringToSign, privateKey){
	//calculate the signature needed for authentication
	var hash = CryptoJS.HmacSHA1(stringToSign, privateKey);
	var base64 = hash.toString(CryptoJS.enc.Base64);
	return encodeURIComponent(base64);
}

//set variables
var d = new Date;
var expiration = 3600; // 1 hour,
var unixtime = parseInt(d.getTime() / 1000);
var future_unixtime = unixtime + expiration;
var	publicKey = "your_public_key";
var	privateKey = "your_private_key";
var	method = "PUT";
var route = "forms";

stringToSign = publicKey + ":" + method + ":" + route + ":" + future_unixtime;
sig = CalculateSig(stringToSign, privateKey);
var url = 'http://localhost/wp.dev/gravityformsapi/' + route + '?api_key=' + publicKey + '&signature=' + sig + '&expires=' + future_unixtime;

var forms = [
	{
		id		: 67,
		title		: 'API Generated Form 1 Update',
		description	: 'This is the description for the form generated by the API',
		labelPlacement	: 'top_label',
		button		: {type : 'text'},
		confirmations	: [
			{id : '0', name : 'Default Confirmation', type : 'message', message : 'Thanks for contacting us! We will get in touch with you shortly.', isDefault : true}
		],
		fields		: [
			{id : '1', label : 'My Text Updated X', type : 'text'},
			{id : '2', label : 'More Text Updated X', type : 'text'},
			{id : '3', label : 'Email Updated X', type : 'email'}
		],
	},
	{
		id		: 68,
		title		: 'API Generated Form 2',
		description	: 'This is the description for the form generated by the API',
		labelPlacement	: 'top_label',
		button		: {type : 'text'},
		confirmations	: [
			{id : '0', name : 'Default Confirmation', type : 'message', message : 'Thanks for contacting us! We will get in touch with you shortly.', isDefault : true}
		],
		fields		: [
			{id : '1', label : 'My Text 2x', type : 'text'},
			{id : '2', label : 'More Text 2x', type : 'text'},
			{id : '3', label : 'Email 2x', type : 'email'}
		],
	}
];

form_json = JSON.stringify(forms);

$.ajax({
	url: url,
	type: 'PUT',
	data: form_json,
	contentType:'application/json',
	success: function(result) {alert('success');},
	error: function(result, textStatus, errorThrown){alert('error ' + errorThrown);}
});
</script>

Sample output from the code above:

{"status":200,"response":"Forms updated successfully"}

DELETE /forms/[Form IDs]

Deletes the forms with the given IDs

  • URI: /gravityformsapi/forms/[Form ID or Form IDs]
    /gravityformsapi/forms/1
    /gravityformsapi/forms/1;4;8
    
  • Output: A localized message describing the results e.g. Forms deleted successfully: 2
  • Notes: If a list of form ids is provided, and a form in the list cannot be found, processing ends and the rest of the forms are not deleted.
  • Potential Errors:
    If a form in the list to be deleted is not found in the database, the following message is displayed:

    {"status":404,"response":{"code":"not_found","message":"Form with id: 67 not found","data":"67"}}
  • Example:

PHP

//set API keys
$api_key = 'your_api_key';
$private_key = 'your_private_key';

//set route
$route = 'forms/67;68';

//creating request URL
$expires = strtotime( '+60 mins' );
$string_to_sign = sprintf( '%s:%s:%s:%s', $api_key, 'DELETE', $route, $expires );
$sig = self::calculate_signature( $string_to_sign, $private_key );
$url = 'http://localhost/wp/gravityformsapi/' . $route . '?api_key=' . $api_key . '&signature=' . $sig . '&expires=' . $expires;

//retrieve data
$response = wp_remote_request( urlencode( $url ), array( 'method' => 'DELETE' ) );
if ( wp_remote_retrieve_response_code( $response ) != 200 || ( empty( wp_remote_retrieve_body( $response ) ) ) ){
	//http request failed
	die( 'There was an error attempting to access the API.' );
}

//result is in the response "body" and is json encoded.
$body = json_decode( wp_remote_retrieve_body( $response ), true );

if( $body['status'] > 202 ){
	$error = $body['response'];

	//form delete failed, get error information
	$error_code 	= $error['code'];
	$error_message 	= $error['message'];
	$error_data 	= isset( $error['data'] ) ? $error['data'] : '';
	$status 	    = "Code: {$error_code}. Message: {$error_message}. Data: {$error_data}.";
	die( "Could not delete forms. {$status}" );
}

JavaScript
WARNING: This sample JavaScript is not secure and it’s not intended to be used on production sites. Never send your private key to the browser. Consider using WordPress cookie authentication instead.

<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/hmac-sha1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/enc-base64-min.js"></script>
<script type="text/javascript">
function CalculateSig(stringToSign, privateKey){
	//calculate the signature needed for authentication
	var hash = CryptoJS.HmacSHA1(stringToSign, privateKey);
	var base64 = hash.toString(CryptoJS.enc.Base64);
	return encodeURIComponent(base64);
}

//set variables
var d = new Date;
var expiration = 3600; // 1 hour,
var unixtime = parseInt(d.getTime() / 1000);
var future_unixtime = unixtime + expiration;
var	publicKey = "your_public_key";
var	privateKey = "your_private_key";
var	method = "DELETE";
var route = "forms/42;43";

stringToSign = publicKey + ":" + method + ":" + route + ":" + future_unixtime;
sig = CalculateSig(stringToSign, privateKey);
var url = 'http://localhost/wp.dev/gravityformsapi/' + route + '?api_key=' + publicKey + '&signature=' + sig + '&expires=' + future_unixtime;

$.ajax({
	url: url,
	type: 'DELETE',
	contentType:'application/json',
	success: function(result) {document.write(result)},
	error: function(result, textStatus, errorThrown){alert('error ' + errorThrown);}
});
</script>

Sample output from the code above:

{"status":200,"response":"Forms deleted successfully: 2"}

Form Submissions

For more detailed examples of how to work with form submissions, go to REST API v1 Examples.

POST /forms/[Form ID]/submissions

Submits a form. Use this function to send input values through the complete form submission process.
Supports field validation, notifications, confirmations, multiple-pages, save & continue and all the filters and actions that fire throughout the submission process.

This is exactly equivalent to submitting a form rendered by a Gravity Forms shortcode. The input names expected by this function are identical to the input names found in the form markup so if you have any doubts about the name of an input, just check the form preview. This is a wrapper for the GFAPI::submit_form() function.
This is the only endpoint which does not require authentication.

  • URI: /gravityformsapi/forms/[Form ID]/submissions
  • Input: A JSON object containing each of the name-value pairs.
    {
        "input_values": {
            "input_1": "Hello",
            "input_2_3": "John",
            "input_2_6": "Smith",
            "input_4": "My paragraph"
        }
    }
    

  • Output: A JSON object containing the result.
    Example in the case of a successful submission:

    {
    	"is_valid": true,
    	"page_number": 0,
    	"source_page_number": 1,
    	"confirmation_message": "this is the confirmation [snipped]"
    }
    

Example in the case of a validation failure:

{
	"is_valid": false,
	"validation_messages": {
                "2": "This field is required. Please enter the first and last name.",
                "3": "Please enter a valid email address."
	},
	"page_number": 1,
	"source_page_number": 1,
	"confirmation_message": ""
}

* Potential Errors:
If the form id provided cannot be found (doesn’t exist, is inactive, is in the trash), a “form_not_found” error will be output:

{"status":400,"response":{"code":"form_not_found","message":"Your form could not be found"}}

If input_values is empty, a bad request error will be output:

{"status":400,"response":"Bad request"}

* Notes:
You cannot upload files using this method. To send pricing fields, you must check the setting “Allow field to be populated dynamically”.

  • Example:
    The example below submits form id 96 with field id 1 (input_1) set to “Testing”.

PHP

//set route
$route = 'forms/96/submissions';

//creating request URL
$url = 'http://localhost/wpdev/gravityformsapi/' . $route;

$values = array(
		'input_values' => array(
					'input_1'	=> 'Testing',
		)
);

//json encode array
$values_json = json_encode( $values );

//retrieve data
$response = wp_remote_request( urlencode( $url ), array( 'method' => 'POST', 'body' => $values_json ) );
if ( wp_remote_retrieve_response_code( $response ) != 200 || ( empty( wp_remote_retrieve_body( $response ) ) ) ){
	//http request failed
	die( 'There was an error attempting to access the API.' );
}

//result is in the response "body" and is json encoded.
$body = json_decode( wp_remote_retrieve_body( $response ), true );

if( $body['status'] > 202 ){
	$error = $body['response'];

	if ( is_array( $error ) ) {
		//get error information
		$error_code 	= $error['code'];
		$error_message 	= $error['message'];
		$error_data 	= isset( $error['data'] ) ? $error['data'] : '';
		$status 	    = "Code: {$error_code}. Message: {$error_message}. Data: {$error_data}.";
		die( "Could not complete form submission. {$status}" );
	}
	else{
		die( $error );
	}
}
else{
	if ( $body['response']['is_valid' ] ){
		echo $body['response']['confirmation_message'];
	}
	else{
		$form = GFFormsModel::get_form_meta(96);
		$result = '';
		$validation_messages = $body['response']['validation_messages'];
		foreach ( $validation_messages as $id => $message ){
			$field = GFFormsModel::get_field( $form, $id );
			$result .= 'Field ' . GFFormsModel::get_label( $field )  . ' (id: ' . $id . ') - ' . $message . '</br>';
		}
		echo $result;
	}
}

JavaScript
WARNING: This sample JavaScript is not secure and it’s not intended to be used on production sites. Never send your private key to the browser. Consider using WordPress cookie authentication instead.

<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/hmac-sha1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/enc-base64-min.js"></script>
<script type="text/javascript">
function CalculateSig(stringToSign, privateKey){
	//calculate the signature needed for authentication
	var hash = CryptoJS.HmacSHA1(stringToSign, privateKey);
	var base64 = hash.toString(CryptoJS.enc.Base64);
	return encodeURIComponent(base64);
}

//set variables
var d = new Date;
var expiration = 3600; // 1 hour,
var unixtime = parseInt(d.getTime() / 1000);
var future_unixtime = unixtime + expiration;
var	publicKey = "your_public_key";
var	privateKey = "your_private_key";
var	method = "POST";
var route = "forms/96/submissions";

stringToSign = publicKey + ":" + method + ":" + route + ":" + future_unixtime;
sig = CalculateSig(stringToSign, privateKey);
var url = 'http://localhost/wp.dev/gravityformsapi/' + route + '?api_key=' + publicKey + '&signature=' + sig + '&expires=' + future_unixtime;

var values = {input_values : {input_1 : 'Testing'}}

//json encode array
values_json = JSON.stringify(values);

$.post(url, values_json, function(data){
	console.log(data.response);
});
</script>

Entries

For more detailed examples of how to work with entries, go to REST API v1 Examples.

GET /entries

Returns the latest entries across all forms.

  • URI: /gravityformsapi/entries
  • Capability: gravityforms_view_entries
  • Output: A JSON string containing a collection of entry objects
  • Notes: Use the Paging parameter to limit the number of entries otherwise you may find the database times out. On most servers we have found the optimum page size to be 200.
  • Parameters:
    • Paging – Controls the number of entries retrieved per page and allows paging to be implemented
    • Sorting – Allows entries to be sorted by a specific field and to be sorted ascending/descending.
    • Search – Allows entries to be filtered by search criteria and field filters.
  • Example:
    The example below retrieves all entries across all forms with paging set to be 5 entries per page:

PHP

//set API keys
$api_key = 'your_api_key';
$private_key = 'your_private_key';

//set route
$route = 'entries';

//set paging properties.
$page_size = 5; //five items will be returned
$offset = 5;    //second page of results will be returned (first page had results 0-4, this needs to start with result 5 to see second page)

//creating request URL
$expires = strtotime( '+60 mins' );
$string_to_sign = sprintf( '%s:%s:%s:%s', $api_key, 'GET', $route, $expires );
$sig = calculate_signature( $string_to_sign, $private_key );
$url = 'http://localhost/wp/gravityformsapi/' . $route . '?api_key=' . $api_key . '&signature=' . $sig . '&expires=' . $expires . '&paging[page_size]=' . $page_size . '&paging[offset]=' . $offset;

//retrieve data
$response = wp_remote_request( urlencode( $url ), array( 'method' => 'GET' ) );
if ( wp_remote_retrieve_response_code( $response ) != 200 || ( empty( wp_remote_retrieve_body( $response ) ) ) ){
	//http request failed
	die( 'There was an error attempting to access the API.' );
}

//result is in the response "body" and is json encoded.
$body = json_decode( wp_remote_retrieve_body( $response ), true );

if( $body['status'] > 202 ){
	$error = $body['response'];
	die( "Could not retrieve entries. Code: {$error['code']}. Message: {$error['message']}. Data: {$error['data']}." );
}

//entries retrieved successfully
$entries         = $body['response']['entries'];
$total       	 = $body['response']['total_count']; //Takes into account all entries including ones outside the current retrieved page.

//To access each entry, loop through the $entries array.
foreach ( $entries as $entry ){
	$entry_id = $entry['id'];
	$data_created = $entry['date_created'];
	$field_1 = $entry['1']; //Data for field with ID = 1.
}

function calculate_signature( $string, $private_key ) {
	$hash = hash_hmac( 'sha1', $string, $private_key, true );
	$sig = rawurlencode( base64_encode( $hash ) );
	return $sig;
}

JavaScript
WARNING: This sample JavaScript is not secure and it’s not intended to be used on production sites. Never send your private key to the browser. Consider using WordPress cookie authentication instead.

<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/hmac-sha1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/enc-base64-min.js"></script>
<script type="text/javascript">
function CalculateSig(stringToSign, privateKey){
	//calculate the signature needed for authentication
	var hash = CryptoJS.HmacSHA1(stringToSign, privateKey);
	var base64 = hash.toString(CryptoJS.enc.Base64);
	return encodeURIComponent(base64);
}

//set variables
var d = new Date;
var expiration = 3600; // 1 hour,
var unixtime = parseInt(d.getTime() / 1000);
var future_unixtime = unixtime + expiration;
var	publicKey = "your_public_key";
var	privateKey = "your_private_key";
var	method = "GET";
var route = "entries";
var page_size = 5;

stringToSign = publicKey + ":" + method + ":" + route + ":" + future_unixtime;
sig = CalculateSig(stringToSign, privateKey);
var url = 'http://localhost/wp.dev/gravityformsapi/' + route + '?api_key=' + publicKey + '&signature=' + sig + '&expires=' + future_unixtime;
url += '&paging[page_size]=' + page_size;

$.get(url, function(data, textStatus)
{
	console.log(data.status);
	console.log(url);
	//get the data from the api
	if ( data.status != 200 || ( typeof( data ) != 'object' ) ) {
		//http request failed
		document.write( 'There was an error attempting to access the API - ' + data.status + ': ' + data.response );
		return;
	}
	response    = data.response;
	entries     = response.entries; //entries is a collection of Entry objects
	total_count = response.total_count;
});
</script>

Sample JSON output from the code above:

 {"status":200,"response":{"total_count":"155","entries":[{"id":"163","form_id":"28","date_created":"2015-07-01 20:03:09","is_starred":0,"is_read":1,"ip":"::1","source_url":"http:\/\/localhost\/wp\/?gf_page=preview&id=28","post_id":null,"currency":"USD","payment_status":null,"payment_date":null,"transaction_id":null,"payment_amount":null,"payment_method":null,"is_fulfilled":null,"created_by":"1","transaction_type":null,"user_agent":"Mozilla\/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko\/20100101 Firefox\/38.0","status":"spam","1.3":"July","1.6":"First","2":"test","1.2":"","1.4":"","1.8":"","3":""},{"id":"162","form_id":"28","date_created":"2015-06-24 20:01:31","is_starred":0,"is_read":0,"ip":"::1","source_url":"http:\/\/localhost\/wp\/?gf_page=preview&id=28","post_id":null,"currency":"USD","payment_status":null,"payment_date":null,"transaction_id":null,"payment_amount":null,"payment_method":null,"is_fulfilled":null,"created_by":"1","transaction_type":null,"user_agent":"Mozilla\/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko\/20100101 Firefox\/38.0","status":"trash","1.3":"d5","1.6":"d5","2":"d5","1.2":"","1.4":"","1.8":"","3":""},{"id":"161","form_id":"28","date_created":"2015-06-24 20:01:06","is_starred":0,"is_read":0,"ip":"::1","source_url":"http:\/\/localhost\/wp\/?gf_page=preview&id=28","post_id":null,"currency":"USD","payment_status":null,"payment_date":null,"transaction_id":null,"payment_amount":null,"payment_method":null,"is_fulfilled":null,"created_by":"1","transaction_type":null,"user_agent":"Mozilla\/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko\/20100101 Firefox\/38.0","status":"active","1.3":"d4","1.6":"d4","2":"d4","1.2":"","1.4":"","1.8":"","3":""},{"id":"157","form_id":"28","date_created":"2015-06-15 22:43:23","is_starred":0,"is_read":1,"ip":"::1","source_url":"http:\/\/localhost\/wp\/?gf_page=preview&id=28","post_id":null,"currency":"USD","payment_status":null,"payment_date":null,"transaction_id":null,"payment_amount":null,"payment_method":"","is_fulfilled":null,"created_by":"1","transaction_type":null,"user_agent":"Mozilla\/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko\/20100101 Firefox\/38.0","status":"active","1.3":"Lee","1.6":"Draven","2":"brandonlee","3":"The Crow","1.2":"","1.4":"","1.8":""},{"id":"156","form_id":"28","date_created":"2015-06-15 22:42:36","is_starred":0,"is_read":1,"ip":"::1","source_url":"http:\/\/localhost\/wp\/?gf_page=preview&id=28","post_id":null,"currency":"USD","payment_status":null,"payment_date":null,"transaction_id":null,"payment_amount":null,"payment_method":"","is_fulfilled":null,"created_by":"1","transaction_type":null,"user_agent":"Mozilla\/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko\/20100101 Firefox\/38.0","status":"active","1.3":"Ellen","1.6":"Ripley","2":"aliens","1.2":"","1.4":"","1.8":"","3":""}]}}

GET /entries/[Entry ID]

Returns the entry that matches the given entry id

  • URI: /gravityformsapi/entries/[Entry ID]
  • Capability: gravityforms_view_entries
  • Output: A JSON string containing the entry object
  • Potential Errors:
    If the entry is not found, a ‘not_found’ error will be output:

    {"status":404,"response":{"code":"not_found","message":"Entry with id 1000 not found","data":"1000"}}
  • Example:
    The example below retrieves the entry with id 146:

PHP

//set API keys
$api_key = 'your_api_key';
$private_key = 'your_private_key';

//set route
$route = 'entries/146';

//creating request URL
$expires = strtotime( '+60 mins' );
$string_to_sign = sprintf( '%s:%s:%s:%s', $api_key, 'GET', $route, $expires );
$sig = calculate_signature( $string_to_sign, $private_key );
$url = 'http://localhost/wp/gravityformsapi/' . $route . '?api_key=' . $api_key . '&signature=' . $sig . '&expires=' . $expires;

//retrieve data
$response = wp_remote_request( urlencode( $url ), array( 'method' => 'GET' ) );
if ( wp_remote_retrieve_response_code( $response ) != 200 || ( empty( wp_remote_retrieve_body( $response ) ) ) ){
	//http request failed
	die( 'There was an error attempting to access the API.' );
}

//result is in the response "body" and is json encoded.
$body = json_decode( wp_remote_retrieve_body( $response ), true );

if( $body['status'] > 202 ){
	$error = $body['response'];
	die( "Could not retrieve entry. Code: {$error['code']}. Message: {$error['message']}. Data: {$error['data']}." );
}

//entry retrieved successfully
$entry = $body['response'];

$entry_id = $entry['id'];
$data_created = $entry['date_created'];
$field_1 = $entry['1']; //Data for field with ID = 1.

function calculate_signature( $string, $private_key ) {
  $hash = hash_hmac( 'sha1', $string, $private_key, true );
  $sig = rawurlencode( base64_encode( $hash ) );
  return $sig;
}

JavaScript
WARNING: This sample JavaScript is not secure and it’s not intended to be used on production sites. Never send your private key to the browser. Consider using WordPress cookie authentication instead.

<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/hmac-sha1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/enc-base64-min.js"></script>
<script type="text/javascript">
function CalculateSig(stringToSign, privateKey){
	//calculate the signature needed for authentication
	var hash = CryptoJS.HmacSHA1(stringToSign, privateKey);
	var base64 = hash.toString(CryptoJS.enc.Base64);
	return encodeURIComponent(base64);
}

//set variables
var d = new Date;
var expiration = 3600; // 1 hour,
var unixtime = parseInt(d.getTime() / 1000);
var future_unixtime = unixtime + expiration;
var	publicKey = "your_public_key";
var	privateKey = "your_private_key";
var	method = "GET";
var route = "entries/146";

stringToSign = publicKey + ":" + method + ":" + route + ":" + future_unixtime;
sig = CalculateSig(stringToSign, privateKey);
var url = 'http://localhost/wp.dev/gravityformsapi/' + route + '?api_key=' + publicKey + '&signature=' + sig + '&expires=' + future_unixtime;

$.get(url, function(data, textStatus)
{
	//get the data from the api
	if ( data.status != 200 || ( typeof( data ) != 'object' ) ) {
		//http request failed
		document.write( 'There was an error attempting to access the API - ' + data.status + ': ' + data.response );
		return;
	}
	response    = data.response;
	console.log(response['id']);
});
</script>

Sample JSON output from the code above:

  {"status":200,"response":{"id":"146","form_id":"28","date_created":"2015-06-15 22:43:23","is_starred":1,"is_read":0,"ip":"::1","source_url":"http:\/\/localhost\/wp\/?gf_page=preview&id=28","post_id":null,"currency":"USD","payment_status":null,"payment_date":null,"transaction_id":null,"payment_amount":null,"payment_method":"","is_fulfilled":null,"created_by":"1","transaction_type":null,"user_agent":"Mozilla\/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko\/20100101 Firefox\/38.0","status":"active","1.3":"Eric","1.6":"Draven","2":"brandonlee","3":"Rapid Fire","1.2":"","1.4":"","1.8":""}}

GET /forms/[Form ID]/entries

Returns the latest entries for the given Form ID.

  • URI: /gravityformsapi/forms/[form ID]/entries
  • Capability: gravityforms_view_entries
  • Output: A JSON string containing a collection of entry objects
  • Parameters:
    • Paging – Controls the number of entries retrieved per page and allows paging to be implemented
    • Sorting – Allows entries to be sorted by a specific field and to be sorted ascending/descending.
    • Search – Allows entries to be filtered by search criteria and field filters.
  • Example:
    The example below retrieves entries for a form. Only 10 entries are retrieved since Paging is not used.

PHP

//set API keys
$api_key = 'your_api_key';
$private_key = 'your_private_key';

//set route
$route = 'forms/28/entries';

//creating request URL
//set API keys
$api_key = 'your_api_key';
$private_key = 'your_private_key';

//set route
$route = 'forms/28/entries';

//creating request URL
$expires = strtotime( '+60 mins' );
$string_to_sign = sprintf( '%s:%s:%s:%s', $api_key, 'GET', $route, $expires );
$sig = calculate_signature( $string_to_sign, $private_key );
$url = 'http://localhost/wp/gravityformsapi/' . $route . '?api_key=' . $api_key . '&signature=' . $sig . '&expires=' . $expires;

//retrieve data
$response = wp_remote_request( urlencode( $url ), array( 'method' => 'GET' ) );
if ( wp_remote_retrieve_response_code( $response ) != 200 || ( empty( wp_remote_retrieve_body( $response ) ) ) ){
	//http request failed
	//echo (wp_remote_retrieve_body( $response ) );
	die( 'There was an error attempting to access the API.' );
}

//result is in the response "body" and is json encoded.
$body = json_decode( wp_remote_retrieve_body( $response ), true );

if( $body['status'] > 202 ){
	$error = $body['response'];
	die( "Could not retrieve entries. Code: {$error['code']}. Message: {$error['message']}. Data: {$error['data']}." );
}

//entries retrieved successfully
$entries         = $body['response']['entries'];
$total       	 = $body['response']['total_count']; //Takes into account all entries including ones outside the current retrieved page.

//To access each entry, loop through the $entries array.
foreach ( $entries as $entry ){
	$entry_id = $entry['id'];
	$data_created = $entry['date_created'];
	$field_1 = $entry['1']; //Data for field with ID = 1.
}

function calculate_signature( $string, $private_key ) {
	$hash = hash_hmac( 'sha1', $string, $private_key, true );
	$sig = rawurlencode( base64_encode( $hash ) );
	return $sig;
}

JavaScript
WARNING: This sample JavaScript is not secure and it’s not intended to be used on production sites. Never send your private key to the browser. Consider using WordPress cookie authentication instead.

<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/hmac-sha1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/enc-base64-min.js"></script>
<script type="text/javascript">
function CalculateSig(stringToSign, privateKey){
  //calculate the signature needed for authentication
  var hash = CryptoJS.HmacSHA1(stringToSign, privateKey);
  var base64 = hash.toString(CryptoJS.enc.Base64);
  return encodeURIComponent(base64);
}

//set variables
var d = new Date;
var expiration = 3600; // 1 hour,
var unixtime = parseInt(d.getTime() / 1000);
var future_unixtime = unixtime + expiration;
var publicKey = "your_public_key";
var privateKey = "your_private_key";
var method = "GET";
var route = "forms/28/entries";

stringToSign = publicKey + ":" + method + ":" + route + ":" + future_unixtime;
sig = CalculateSig(stringToSign, privateKey);
var url = 'http://localhost/wp.dev/gravityformsapi/' + route + '?api_key=' + publicKey + '&signature=' + sig + '&expires=' + future_unixtime;
$.get(url, function(data, textStatus)
{
  //get the data from the api
  if ( data.status != 200 || ( typeof( data ) != 'object' ) ) {
    //http request failed
    document.write( 'There was an error attempting to access the API - ' + data.status + ': ' + data.response );
    return;
  }
  response          = data.response;
  entries           = response.entries; //entries is a collection of Entry objects
  total_count       = response.total_count;
 });

</script>

The response from this example will look like the following if successful:

{"status":200,"response":{"total_count":"13","entries":[{"id":"162","form_id":"28","date_created":"2015-06-24 20:01:31","is_starred":0,"is_read":0,"ip":"::1","source_url":"http:\/\/localhost\/wp\/?gf_page=preview&id=28","post_id":null,"currency":"USD","payment_status":null,"payment_date":null,"transaction_id":null,"payment_amount":null,"payment_method":null,"is_fulfilled":null,"created_by":"1","transaction_type":null,"user_agent":"Mozilla\/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko\/20100101 Firefox\/38.0","status":"active","1.3":"d5","1.6":"d5","2":"d5","1.2":"","1.4":"","1.8":"","3":""},{"id":"161","form_id":"28","date_created":"2015-06-24 20:01:06","is_starred":0,"is_read":0,"ip":"::1","source_url":"http:\/\/localhost\/wp\/?gf_page=preview&id=28","post_id":null,"currency":"USD","payment_status":null,"payment_date":null,"transaction_id":null,"payment_amount":null,"payment_method":null,"is_fulfilled":null,"created_by":"1","transaction_type":null,"user_agent":"Mozilla\/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko\/20100101 Firefox\/38.0","status":"active","1.3":"d4","1.6":"d4","2":"d4","1.2":"","1.4":"","1.8":"","3":""},{"id":"157","form_id":"28","date_created":"2015-06-15 22:43:23","is_starred":0,"is_read":1,"ip":"::1","source_url":"http:\/\/localhost\/wp\/?gf_page=preview&id=28","post_id":null,"currency":"USD","payment_status":null,"payment_date":null,"transaction_id":null,"payment_amount":null,"payment_method":"","is_fulfilled":null,"created_by":"1","transaction_type":null,"user_agent":"Mozilla\/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko\/20100101 Firefox\/38.0","status":"active","1.3":"Eric","1.6":"Draven","2":"brandonlee","3":"The Crow","1.2":"","1.4":"","1.8":""},{"id":"156","form_id":"28","date_created":"2015-06-15 22:42:36","is_starred":0,"is_read":1,"ip":"::1","source_url":"http:\/\/localhost\/wp\/?gf_page=preview&id=28","post_id":null,"currency":"USD","payment_status":null,"payment_date":null,"transaction_id":null,"payment_amount":null,"payment_method":"","is_fulfilled":null,"created_by":"1","transaction_type":null,"user_agent":"Mozilla\/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko\/20100101 Firefox\/38.0","status":"active","1.3":"Ellen","1.6":"Ripley","2":"aliens","1.2":"","1.4":"","1.8":"","3":""},{"id":"155","form_id":"28","date_created":"2015-06-15 22:42:15","is_starred":0,"is_read":0,"ip":"::1","source_url":"http:\/\/localhost\/wp\/?gf_page=preview&id=28","post_id":null,"currency":"USD","payment_status":null,"payment_date":null,"transaction_id":null,"payment_amount":null,"payment_method":null,"is_fulfilled":null,"created_by":"1","transaction_type":null,"user_agent":"Mozilla\/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko\/20100101 Firefox\/38.0","status":"active","1.3":"James","1.6":"Kirk","2":"captain","1.2":"","1.4":"","1.8":"","3":""},{"id":"154","form_id":"28","date_created":"2015-06-15 22:41:56","is_starred":0,"is_read":0,"ip":"::1","source_url":"http:\/\/localhost\/wp\/?gf_page=preview&id=28","post_id":null,"currency":"USD","payment_status":null,"payment_date":null,"transaction_id":null,"payment_amount":null,"payment_method":null,"is_fulfilled":null,"created_by":"1","transaction_type":null,"user_agent":"Mozilla\/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko\/20100101 Firefox\/38.0","status":"active","1.3":"Jean-Luc","1.6":"Picard","2":"captain","1.2":"","1.4":"","1.8":"","3":""},{"id":"153","form_id":"28","date_created":"2015-06-15 22:41:33","is_starred":0,"is_read":0,"ip":"::1","source_url":"http:\/\/localhost\/wp\/?gf_page=preview&id=28","post_id":null,"currency":"USD","payment_status":null,"payment_date":null,"transaction_id":null,"payment_amount":null,"payment_method":null,"is_fulfilled":null,"created_by":"1","transaction_type":null,"user_agent":"Mozilla\/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko\/20100101 Firefox\/38.0","status":"active","1.3":"Wesley","1.6":"Crusher","2":"ensign","1.2":"","1.4":"","1.8":"","3":""},{"id":"152","form_id":"28","date_created":"2015-06-15 22:41:07","is_starred":0,"is_read":0,"ip":"::1","source_url":"http:\/\/localhost\/wp\/?gf_page=preview&id=28","post_id":null,"currency":"USD","payment_status":null,"payment_date":null,"transaction_id":null,"payment_amount":null,"payment_method":null,"is_fulfilled":null,"created_by":"1","transaction_type":null,"user_agent":"Mozilla\/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko\/20100101 Firefox\/38.0","status":"active","1.3":"Sam","1.6":"Winchester","2":"computer","1.2":"","1.4":"","1.8":"","3":""},{"id":"151","form_id":"28","date_created":"2015-06-15 22:40:48","is_starred":0,"is_read":0,"ip":"::1","source_url":"http:\/\/localhost\/wp\/?gf_page=preview&id=28","post_id":null,"currency":"USD","payment_status":null,"payment_date":null,"transaction_id":null,"payment_amount":null,"payment_method":null,"is_fulfilled":null,"created_by":"1","transaction_type":null,"user_agent":"Mozilla\/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko\/20100101 Firefox\/38.0","status":"active","1.3":"Dean","1.6":"Winchester","2":"supernatural","1.2":"","1.4":"","1.8":"","3":""},{"id":"150","form_id":"28","date_created":"2015-06-15 22:40:29","is_starred":0,"is_read":0,"ip":"::1","source_url":"http:\/\/localhost\/wp\/?gf_page=preview&id=28","post_id":null,"currency":"USD","payment_status":null,"payment_date":null,"transaction_id":null,"payment_amount":null,"payment_method":null,"is_fulfilled":null,"created_by":"1","transaction_type":null,"user_agent":"Mozilla\/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko\/20100101 Firefox\/38.0","status":"active","1.3":"Rupert","1.6":"Giles","2":"sunnydale","1.2":"","1.4":"","1.8":"","3":""}]}}

If no entries are located for the specified form, the response will look like the following:

{"status":200,"response":{"total_count":"0","entries":[]}}

GET /forms/[Form ID]/entries/[Entry ID]/fields/[Field ID]

Returns the specified entry property/properties for the specified entry/entries.

  • URI:/gravityformsapi/entries/[Entry ID]/fields/[Field ID or entry meta key]
    //retrieve field id 1.3 for entry id 146
    http://[your_domain]/gravityformsapi/entries/146/fields/1.3
    
    //retrieve field ids 1.3 and 1.6 with fields id, form_id, date_created, is_starred
    //for entry ids 146 and 147
    http://[your_domain]/gravityformaspi/entries/146;147/fields/id;form_id;date_created;is_starred;1.3;1.6;
      
  • Capability:gravityforms_view_entries
  • Output: A JSON string containing the filtered entry object
  • Potential Errors:
    If the entry is not found, a ‘not_found’ error will be output. If multiple entries are being retrieved and the last entry is not found, no entries will be retrieved.

    {"status":404,"response":{"code":"not_found","message":"Entry with id 1001 not found","data":"1001"}}
  • Notes: The entry meta keys which may be used are listed in the Sorting section.
  • Parameters:
    • Paging – Controls the number of entries retrieved per page and allows paging to be implemented
    • Sorting – Allows entries to be sorted by a specific field and to be sorted ascending/descending.
    • Search – Allows entries to be filtered by search criteria and field filters.
  • Example:
    The example below retrieves specific fields for a single entry:

PHP

//set API keys
$api_key = 'your_api_key';
$private_key = 'your_private_key';

//set route
$route = 'entries/1000/fields/id;form_id;date_created;is_starred;is_read;1.3;1.6;';

//creating request URL
$expires = strtotime( '+60 mins' );
$string_to_sign = sprintf( '%s:%s:%s:%s', $api_key, 'GET', $route, $expires );
$sig = calculate_signature( $string_to_sign, $private_key );
$url = 'http://localhost/wp/gravityformsapi/' . $route . '?api_key=' . $api_key . '&signature=' . $sig . '&expires=' . $expires;

//retrieve data
$response = wp_remote_request( urlencode( $url ), array( 'method' => 'GET' ) );
if ( wp_remote_retrieve_response_code( $response ) != 200 || ( empty( wp_remote_retrieve_body( $response ) ) ) ){
	//http request failed
	//echo (wp_remote_retrieve_body( $response ) );
	die( 'There was an error attempting to access the API.' );
}


//result is in the response "body" and is json encoded.
$body = json_decode( wp_remote_retrieve_body( $response ), true );

if( $body['status'] > 202 ){
	$error = $body['response'];
	die( "Could not retrieve entry. Code: {$error['code']}. Message: {$error['message']}. Data: {$error['data']}." );
}

//entry retrieved successfully
$entry = $body['response'];

$entry_id = $entry['id'];
$data_created = $entry['date_created'];
$field_1 = $entry['1']; //Data for field with ID = 1.

function calculate_signature( $string, $private_key ) {
	$hash = hash_hmac( 'sha1', $string, $private_key, true );
	$sig = rawurlencode( base64_encode( $hash ) );
	return $sig;
}

JavaScript
WARNING: This sample JavaScript is not secure and it’s not intended to be used on production sites. Never send your private key to the browser. Consider using WordPress cookie authentication instead.

<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/hmac-sha1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/enc-base64-min.js"></script>
<script type="text/javascript">
function CalculateSig(stringToSign, privateKey){
	//calculate the signature needed for authentication
	var hash = CryptoJS.HmacSHA1(stringToSign, privateKey);
	var base64 = hash.toString(CryptoJS.enc.Base64);
	return encodeURIComponent(base64);
}

//set variables
var d = new Date;
var expiration = 3600; // 1 hour,
var unixtime = parseInt(d.getTime() / 1000);
var future_unixtime = unixtime + expiration;
var	publicKey = "your_public_key";
var	privateKey = "your_private_key";
var	method = "GET";
var route = 'entries/24/fields/id;form_id;date_created;is_starred;is_read;2.3;2.6;';

stringToSign = publicKey + ":" + method + ":" + route + ":" + future_unixtime;
sig = CalculateSig(stringToSign, privateKey);
var url = 'http://localhost/wp.dev/gravityformsapi/' + route + '?api_key=' + publicKey + '&signature=' + sig + '&expires=' + future_unixtime;

$.get(url, function(data, textStatus)
{
	//get the data from the api
	if ( data.status != 200 || ( typeof( data ) != 'object' ) ) {
		//http request failed
		document.write( 'There was an error attempting to access the API - ' + data.status + ': ' + data.response );
		return;
	}
	response = data.response;

	console.log(response);
});

Querystring Parameters for Retrieval Routes

There are four important features that may be set as querystring parameters included with the URI when retrieving entries:

NOTE: The examples below do not include the required api_key, expires, or signature querystring parameter values for ease of reading.

Paging

By default, only 10 results are retrieved. This can be changed by specifying the page_size within the querystring as part of the paging parameter.

http://localhost/wp/gravityformsapi/forms/28/entries/?paging[page_size]=5

Along with specifying a page size, a offset may also be set with the paging parameter. This is set to 0 by default. Using the page offset comes into play when displaying entries with the ability for the user to go to the next or previous set of results. The page offset controls which set of results are displayed as the user navigates through the pages. If the page size is set to 5 and the offset is 0, then results 0 – 4 are displayed. To see the next set of results, the page offset would be set to 5, displaying results 5 – 9 (actually the sixth through tenth results since the offset starts at zero), and the next page offset would be 10, displaying results 10 – 14 (eleventh through fifteenth since the offset starts at zero).

http://localhost/wp/gravityformsapi/forms/28/entries/?paging[page_size]=5&paging[offset]=10

Sorting

Retrieved entries are automatically sorted by entry id, descending. This means the most recently created entries are first. This may be changed by specifying a sorting key (key) and a sorting direction (direction) within the sorting querystring parameter. The possible values for the sorting direction are:

  • ASC
  • DESC
http://localhost/wp/gravityformsapi/forms/28/entries/?sorting[direction]=ASC

To specify a sorting key, field ids or an entry meta key may be used. The entry meta keys which are available for sorting are as follows:

  • id
  • form_id
  • post_id
  • date_created
  • is_starred
  • is_read
  • ip
  • source_url
  • user_agent
  • created_by
  • status
  • currency

For entries with payment information:

  • payment_status
  • payment_date
  • payment_amount
  • payment_method
  • transaction_id
  • transaction_type
  • is_fulfilled
//example using a field id
http://localhost/wp/gravityformsapi/forms/28/entries/?sorting[key]=1.3

//example using an entry meta key
http://localhost/wp/gravityformsapi/forms/28/entries/?sorting[key]=is_starred

//example with sorting key and direction
http://localhost/wp/gravityformsapi/forms/28/entries/?sorting[key]=form_id&sorting[direction]=ASC

Search Criteria

Specifying search criteria allows the results retrieved to be filtered into a subset of data, using specific entry meta. To specify search criteria, use search in the querystring along with an entry meta key and a value. The entry meta keys which are available to use as search criteria are as follows:

  • start_date
  • end_date
  • status

If filtering needs to be done using any other set of data, it is necessary to use field filters.

//example using status
http://localhost/wp/gravityformsapi/forms/28/entries/?search[status]=trash

//example using a specific date
http://localhost/wp/gravityformsapi/forms/28/entries/?search[start_date]=2015-06-24

//example using a date range
http://localhost/wp/gravityformsapi/forms/28/entries/?search[start_date]=2015-06-15&search[end_date]=2015-06-24

Field Filters

Field filters are an extension of search criteria that provides more flexibility with specifying multiple sets of data conditionally. The search may be done so that all or any of the criteria is met. The values provided may be set to match, not match, or be contained in the results. Field filters are structured into an array with child arrays for each criteria set. When using field filters, the value of the search argument needs to be a JSON string. The JSON string needs to be URL-encoded before it is used in the querystring to maintain the JSON formatting. Field filters may be broken down into the following:

  • mode – indicates whether all conditions need to be met or any of them. The possible values are all (AND is used in the database query) or any (OR is used in the database query). The default mode is “all” so you do not need to include the mode when all conditions are required. The “mode” is contained in a top level array.
  • key – the field id or entry meta being used to filter data
  • operator – indicates how the data should be compared. The possible values are is, isnot, contains.
  • value – the data used for comparison

The key, operator, and value together make up the child array and each piece is required for a criteria set. Below is an example of what the array would look like:

array (
        'mode' => 'any',
        array(
               'key'      => '1.6',
               'operator' => 'is',
               'value'    => 'Draven'
        ),
        array(
               'key'      => '1.3',
               'operator' => 'isnot',
               'value'    => 'Eric'
        )
);

Once the array is JSON-encoded, the string will look like the following:

{"field_filters":{"mode":"any","0":{"key":"1.6","operator":"is","value":"Draven"},"1":{"key":"1.3","operator":"isnot","value":"Eric"}}}

Field filters may be used in combination with Search Criteria.

Below is an example on creating an array that contains both search criteria and field filters:

PHP

$search = array(
		'field_filters' => array (
			                array(
						'key' 		=> '1.6',
						'operator'	=> 'contains',
						'value' 	=> 'Test'
					),
					array(
						'key'		=> '1.3',
						'operator'	=> 'is',
						'value'		=> 'Test'
					)
				),
		'start_date' => '2016-10-10'
	);
$search_json = urlencode( json_encode( $search ) );
$url .= '&search=' . $search_json;

JavaScript

var search = {
		field_filters : [
			{
				key: '1.6',
				operator: 'contains',
				value: 'Test'
			},
                        {
                               key: '1.3',
                               operator: 'is',
                               value: 'Test'
                        }
		],
		start_date : '2016-10-10'
	};

//convert to a JSON string and url encode it so the JSON formatting persists
search = encodeURI(JSON.stringify(search));

//add search to url
url += '&search=' + search;

POST /entries

Creates/adds entries

  • URI: /gravityformsapi/entries
  • Capability: gravityforms_edit_entries
  • Input: A JSON string containing a collection of entries that will be added
  • Output: A localized message describing the result: “Entries created successfully” with the entry ids that were inserted
  • Potential Errors:
    If the entry information passed over to the API is not an array, an invalid_entry_object error code is returned:

    {"status":error_code,"response":{"code":"invalid_entry_object","message":"The entry object must be an array"}}

    If a form id is not provided for an entry, an empty_form_id error code is returned:

    {"status":400,"response":{"code":"empty_form_id","message":"The form id must be specified"}}

    If an invalid form id is provided, an invalid_form_id error code is returned:

     {"status":400,"response":{"code":"invalid_form_id","message":"The form for this entry does not exist"}}

    If there is a problem inserting the entry in the database, the following message is displayed, along with the applicable SQL error, if one exists:

    {"status":error code,"response":{"code":"insert_entry_properties_failed","message":"There was a problem while inserting the entry properties","data":"sql statement"}

    If there is a problem inserting the value for a field which has inputs, the following message is displayed, along with the applicable SQL error, if one exists:

    {"status":error code,"response":{"code":"insert_input_value_failed","message":"There was a problem while inserting one of the input values for the entry","data":"sql statement"}

    If there is a problem inserting the value for a field, the following message is displayed, along with the applicable SQL error, if one exists.

    {"status":error code,"response":{"code":"insert_field_values_failed","message":"There was a problem while inserting the field values","data":"sql statement"}
  • Notes: If values are not provided for the following entry fields, default values are used:
    • date_created – utc_timestamp()
    • is_starred – 0
    • is_read – 0
    • ip – $_SERVER
    • source_url – http://$_SERVER[‘HTTP_HOST’] . $_SERVER[‘REQUEST_URI’] (If $_SERVER[‘HTTPS’] or force ssl is on, then https is used)
    • user_agent – API
    • currency – USD
    • status – active
    • created_by – current user id if logged in
  • Example:

PHP

//set API keys
$api_key = 'your_api_key';
$private_key = 'your_private_key';

//set route
$route = 'entries';

//creating request URL
$expires = strtotime( '+60 mins' );
$string_to_sign = sprintf( '%s:%s:%s:%s', $api_key, 'POST', $route, $expires );
$sig = calculate_signature( $string_to_sign, $private_key );
$url = 'http://localhost/wp/gravityformsapi/' . $route . '?api_key=' . $api_key . '&signature=' . $sig . '&expires=' . $expires;

$entries = array(
	array(
		'form_id'      => '28',
		'date_created' => '2015-06-15 22:43:23',
		'is_starred'   => 0,
		'is_read'      => 1,
		'ip'           => '::1',
		'source_url'   => 'http://localhost/wp/?gf_page=preview&id=28',
		'currency'     => 'USD',
		'created_by'   => 1,
		'user_agent'   => 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0',
		'status'       => 'active',
		'1.3'          => 'Manually',
		'1.6'          => 'Created Entry 1',
		'2'            => 'Creating using REST API v1',
		'3'            => 'Manually created using the POST route of the REST API v1',
	),
	array(
		'form_id'      => '28',
		'date_created' => '2015-06-15 22:43:23',
		'is_starred'   => 0,
		'is_read'      => 1,
		'ip'           => '::1',
		'source_url'   => 'http://localhost/wp/?gf_page=preview&id=28',
		'currency'     => 'USD',
		'created_by'   => 1,
		'user_agent'   => 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0',
		'status'       => 'active',
		'1.3'          => 'Manually',
		'1.6'          => 'Created Entry 2',
		'2'            => 'This entry was created manually using the REST API v1.',
		'3'            => 'Manually created',
	),
);

//json encode array
$entry_json = json_encode( $entries );

//retrieve data
$response = wp_remote_request( urlencode( $url ), array( 'method' => 'POST', 'body' => $entry_json ) );
if ( wp_remote_retrieve_response_code( $response ) != 200 || ( empty( wp_remote_retrieve_body( $response ) ) ) ){
	//http request failed
	die( 'There was an error attempting to access the API.' );
}

//result is in the response "body" and is json encoded.
$body = json_decode( wp_remote_retrieve_body( $response ), true );

if( $body['status'] > 202 ){
	$error = $body['response'];

        //entry update failed, get error information, error could just be a string
	if ( is_array( $error )){
		$error_code 	= $error['code'];
		$error_message 	= $error['message'];
		$error_data 	= isset( $error['data'] ) ? $error['data'] : '';
		$status 	= "Code: {$error_code}. Message: {$error_message}. Data: {$error_data}.";
	}
	else{
		$status = $error;
	}
	die( "Could not post entries. {$status}" );
}

$entry_ids = $body['response'];
$entry_ids_created = 'The following entry ids were created:</br>';
foreach ( $entry_ids as $entry_id ){
       $entry_ids_created .= $entry_id . '</br>';
}

function calculate_signature( $string, $private_key ) {
	$hash = hash_hmac( 'sha1', $string, $private_key, true );
	$sig = rawurlencode( base64_encode( $hash ) );
	return $sig;
}

JavaScript
WARNING: This sample JavaScript is not secure and it’s not intended to be used on production sites. Never send your private key to the browser. Consider using WordPress cookie authentication instead.

<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/hmac-sha1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/enc-base64-min.js"></script>
<script type="text/javascript">
function CalculateSig(stringToSign, privateKey){
	//calculate the signature needed for authentication
	var hash = CryptoJS.HmacSHA1(stringToSign, privateKey);
	var base64 = hash.toString(CryptoJS.enc.Base64);
	return encodeURIComponent(base64);
}

//set variables
var d = new Date;
var expiration = 3600; // 1 hour,
var unixtime = parseInt(d.getTime() / 1000);
var future_unixtime = unixtime + expiration;
var	publicKey = "your_public_key";
var	privateKey = "your_private_key";
var	method = "POST";
var route = 'entries';

stringToSign = publicKey + ":" + method + ":" + route + ":" + future_unixtime;
sig = CalculateSig(stringToSign, privateKey);
var url = 'http://localhost/wp.dev/gravityformsapi/' + route + '?api_key=' + publicKey + '&signature=' + sig + '&expires=' + future_unixtime;

var entries =
[
	{
		form_id     : '1',
		date_created: '2016-07-29 21:38:23',
		is_starred  : 0,
		is_read     : 1,
		ip          : '::1',
		source_url  : 'http://localhost/wpdev/?gf_page=preview&id=1',
		currency    : 'USD',
		created_by  : 1,
		user_agent  : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0',
		status      : 'active',
		2.3         : 'Testing',
		2.6         : 'Tester',
		1           : 'The Crowsxxxxxxxxxxxxx'
	},
	{
		form_id     : '1',
		date_created: '2016-07-29 21:38:23',
		is_starred  : 1,
		is_read     : 1,
		ip          : '::1',
		source_url  : 'http://localhost/wpdev/?gf_page=preview&id=1',
		currency    : 'USD',
		created_by  : 1,
		user_agent  : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0',
		status      : 'active',
		2.3         : 'Second Testing',
		2.6         : 'Second Tester',
		1           : 'Testing.....'
	}
];

entries_json = JSON.stringify(entries);

$.post(url, entries_json, function(data){
	document.write('Inserted Ids: ' + data.response);
});
</script>

POST /forms/[Form ID]/entries

Creates/adds entries for the specified Form ID

  • URI: /gravityformsapi/forms/[Form ID]/entries
  • Capability: gravityforms_edit_entries
  • Input: A JSON string containing a collection of entries that will be added
  • Output: A localized message describing the result: “Entries created successfully” with the entry ids that were inserted
  • Potential Errors:
    If the entry information passed over to the API is not an array, an invalid_entry_object error code is returned:

    {"status":error_code,"response":{"code":"invalid_entry_object","message":"The entry object must be an array"}}

    If a form id is not provided for an entry, an empty_form_id error code is returned:

    {"status":400,"response":{"code":"empty_form_id","message":"The form id must be specified"}}

    If an invalid form id is provided, an invalid_form_id error code is returned:

     {"status":400,"response":{"code":"invalid_form_id","message":"The form for this entry does not exist"}}

    If there is a problem inserting the entry in the database, the following message is displayed, along with the applicable SQL error, if one exists:

    {"status":error code,"response":{"code":"insert_entry_properties_failed","message":"There was a problem while inserting the entry properties","data":"sql statement"}

    If there is a problem inserting the value for a field which has inputs, the following message is displayed, along with the applicable SQL error, if one exists:

    {"status":error code,"response":{"code":"insert_input_value_failed","message":"There was a problem while inserting one of the input values for the entry","data":"sql statement"}

    If there is a problem inserting the value for a field, the following message is displayed, along with the applicable SQL error, if one exists.

    {"status":error code,"response":{"code":"insert_field_values_failed","message":"There was a problem while inserting the field values","data":"sql statement"}
  • Notes: If values are not provided for the following entry fields, default values are used:
    • date_created – utc_timestamp()
    • is_starred – 0
    • is_read – 0
    • ip – $_SERVER
    • source_url – http://$_SERVER[‘HTTP_HOST’] . $_SERVER[‘REQUEST_URI’] (If $_SERVER[‘HTTPS’] or force ssl is on, then https is used)
    • user_agent – API
    • currency – USD
    • status – active
    • created_by – current user id if logged in
  • Example:

PHP

//set API keys
$api_key = 'your_api_key';
$private_key = 'your_private_key';

//set route
$route = 'forms/28/entries';

//creating request URL
$expires = strtotime( '+60 mins' );
$string_to_sign = sprintf( '%s:%s:%s:%s', $api_key, 'POST', $route, $expires );
$sig = calculate_signature( $string_to_sign, $private_key );
$url = 'http://localhost/wp/gravityformsapi/' . $route . '?api_key=' . $api_key . '&signature=' . $sig . '&expires=' . $expires;

$entries = array(
	array(
		'date_created' => '2015-06-15 22:43:23',
		'is_starred'   => 0,
		'is_read'      => 1,
		'ip'           => '::1',
		'source_url'   => 'http://localhost/wp/?gf_page=preview&id=28',
		'currency'     => 'USD',
		'created_by'   => 1,
		'user_agent'   => 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0',
		'status'       => 'active',
		'1.3'          => 'Manually',
		'1.6'          => 'Created Entry using Form route',
		'2'            => 'Creating using REST API v1',
		'3'            => 'Manually created using the POST route of the REST API v1',
	),
	array(
		'date_created' => '2015-06-15 22:43:23',
		'is_starred'   => 0,
		'is_read'      => 1,
		'ip'           => '::1',
		'source_url'   => 'http://localhost/wp/?gf_page=preview&id=28',
		'currency'     => 'USD',
		'created_by'   => 1,
		'user_agent'   => 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0',
		'status'       => 'active',
		'1.3'          => 'Manually',
		'1.6'          => 'Created Entry 2 using Form route',
		'2'            => 'This entry was created manually using the REST API v1.',
		'3'            => 'Manually created',
	),
);

//json encode array
$entry_json = json_encode( $entries );

//retrieve data
$response = wp_remote_request( urlencode( $url ), array( 'method' => 'POST', 'body' => $entry_json ) );
if ( wp_remote_retrieve_response_code( $response ) != 200 || ( empty( wp_remote_retrieve_body( $response ) ) ) ){
	//http request failed
	die( 'There was an error attempting to access the API.' );
}

//result is in the response "body" and is json encoded.
$body = json_decode( wp_remote_retrieve_body( $response ), true );

if( $body['status'] > 202 ){
	$error = $body['response'];

        //entry update failed, get error information, error could just be a string
	if ( is_array( $error )){
		$error_code 	= $error['code'];
		$error_message 	= $error['message'];
		$error_data 	= isset( $error['data'] ) ? $error['data'] : '';
		$status 	= "Code: {$error_code}. Message: {$error_message}. Data: {$error_data}.";
	}
	else{
		$status = $error;
	}
	die( "Could not post entries. {$status}" );
}

$entry_ids = $body['response'];
$entry_ids_created = 'The following entry ids were created:</br>';
foreach ( $entry_ids as $entry_id ){
       $entry_ids_created .= $entry_id . '</br>';
}

function calculate_signature( $string, $private_key ) {
	$hash = hash_hmac( 'sha1', $string, $private_key, true );
	$sig = rawurlencode( base64_encode( $hash ) );
	return $sig;
}

JavaScript
WARNING: This sample JavaScript is not secure and it’s not intended to be used on production sites. Never send your private key to the browser. Consider using WordPress cookie authentication instead.

<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/hmac-sha1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/enc-base64-min.js"></script>
<script type="text/javascript">
function CalculateSig(stringToSign, privateKey){
	//calculate the signature needed for authentication
	var hash = CryptoJS.HmacSHA1(stringToSign, privateKey);
	var base64 = hash.toString(CryptoJS.enc.Base64);
	return encodeURIComponent(base64);
}

//set variables
var d = new Date;
var expiration = 3600; // 1 hour,
var unixtime = parseInt(d.getTime() / 1000);
var future_unixtime = unixtime + expiration;
var	publicKey = "your_public_key";
var	privateKey = "your_private_key";
var	method = "POST";
var route = 'forms/1/entries';

stringToSign = publicKey + ":" + method + ":" + route + ":" + future_unixtime;
sig = CalculateSig(stringToSign, privateKey);
var url = 'http://localhost/wp.dev/gravityformsapi/' + route + '?api_key=' + publicKey + '&signature=' + sig + '&expires=' + future_unixtime;

var entries =
[
	{
		date_created: '2016-07-29 21:38:23',
		is_starred  : 0,
		is_read     : 1,
		ip          : '::1',
		source_url  : 'http://localhost/wpdev/?gf_page=preview&id=1',
		currency    : 'USD',
		created_by  : 1,
		user_agent  : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0',
		status      : 'active',
		2.3         : 'Testing',
		2.6         : 'Tester',
		1           : 'The Crowsxxxxxxxxxxxxx'
	},
	{
		date_created: '2016-07-29 21:38:23',
		is_starred  : 1,
		is_read     : 1,
		ip          : '::1',
		source_url  : 'http://localhost/wpdev/?gf_page=preview&id=1',
		currency    : 'USD',
		created_by  : 1,
		user_agent  : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0',
		status      : 'active',
		2.3         : 'Second Testing',
		2.6         : 'Second Tester',
		1           : 'Testing.....'
	}
];

entries_json = JSON.stringify(entries);

$.post(url, entries_json, function(data){
	document.write('Inserted Ids: ' + data.response);
});
</script>

PUT /entries/[Entry ID]

Updates the entry with the given ID

  • URI: /gravityformsapi/entries/[Entry ID]
  • Capability: gravityforms_edit_entries
  • Input: A JSON string with the entry. If an entry ID is provided in the entry object, it will NOT be used. The id provided in the request is used. Please see the Entry Object for more details regarding what may be included.
  • Output: A message describing the result: “Entry updated successfully”
  • Potential Errors:
    If the entry id provided cannot be found, a not_found error code is returned:

     {"status":404,"response":{"code":"not_found","message":"Entry with id 1000 not found","data":"1000"}}

    If an invalid form id is provided when updating the entry, an invalid_form_id error code is returned:

    {"status":400,"response":{"code":"invalid_form_id","message":"The form for this entry does not exist"}}

    If there is a problem updating the entry in the database, the following message is displayed, along with the applicable SQL error, if one exists.

    {"status":error code,"response":{"code":"update_entry_properties_failed","message":"There was a problem while updating the entry properties","data":"sql statement"}

    If there is a problem updating the value for a field which has inputs, the following message is displayed, along with the applicable SQL error, if one exists.

    {"status":error code,"response":{"code":"update_input_value_failed","message":"There was a problem while updating one of the input values for the entry","data":"sql statement"}

    If there is a problem updating the value for a field, the following message is displayed, along with the applicable SQL error, if one exists.

    {"status":error code,"response":{"code":"update_field_values_failed","message":"There was a problem while updating the field values","data":"sql statement"}

  • Notes: If values are not provided for the following entry fields, default values are used:

    • date_created – utc_timestamp()
    • is_starred – 0
    • is_read – 0
    • ip – $_SERVER
    • source_url – http://$_SERVER[‘HTTP_HOST’] . $_SERVER[‘REQUEST_URI’] (If $_SERVER[‘HTTPS’] or force ssl is on, then https is used)
    • user_agent – API
    • currency – USD
    • status – active
    • created_by – current user id if logged in
  • Example:

PHP

The example below updates field id 3, read status, starred status for entry id 146. The existing entry object array is retrieved and the values in the array are modified. That array is then what is JSON-encoded and passed along for updating.

//set API keys
$api_key = 'your_api_key';
$private_key = 'your_private_key';

//set route
$route = 'entries/146';

//creating request URL
$expires = strtotime( '+60 mins' );
$string_to_sign = sprintf( '%s:%s:%s:%s', $api_key, 'PUT', $route, $expires );
$sig = calculate_signature( $string_to_sign, $private_key );
$url = 'http://localhost/wp/gravityformsapi/' . $route . '?api_key=' . $api_key . '&signature=' . $sig . '&expires=' . $expires;

$entry = GFAPI::get_entry( 146 );
$entry['3'] = 'Rapid Fire';
$entry['is_read'] = 0;
$entry['is_starred'] = 1;

$entry_json = json_encode( $entry );

$response = wp_remote_request( urlencode( $url ), array( 'method' => 'PUT', 'body' => $entry_json ) );
if ( wp_remote_retrieve_response_code( $response ) != 200 || ( empty( wp_remote_retrieve_body( $response ) ) ) ){
	//http request failed
        die( 'There was an error attempting to access the API.' );
}

//result is in the response "body" and is json encoded.
$body = json_decode( wp_remote_retrieve_body( $response ), true );

if( $body['status'] > 202 ){
	$error = $body['response'];

        //entry update failed, get error information
	$error_code 	= $error['code'];
	$error_message 	= $error['message'];
	$error_data 	= isset( $error['data'] ) ? $error['data'] : '';
	$status 	= "Code: {$error_code}. Message: {$error_message}. Data: {$error_data}.";
}
else{
    //entry updated successfully
    $status  = $status_code;
}

die( "Entry update status: {$status}" );

function calculate_signature( $string, $private_key ) {
	$hash = hash_hmac( 'sha1', $string, $private_key, true );
	$sig = rawurlencode( base64_encode( $hash ) );
	return $sig;
}

JavaScript
WARNING: This sample JavaScript is not secure and it’s not intended to be used on production sites. Never send your private key to the browser. Consider using WordPress cookie authentication instead.

<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/hmac-sha1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/enc-base64-min.js"></script>
<script type="text/javascript">
function CalculateSig(stringToSign, privateKey){
	//calculate the signature needed for authentication
	var hash = CryptoJS.HmacSHA1(stringToSign, privateKey);
	var base64 = hash.toString(CryptoJS.enc.Base64);
	return encodeURIComponent(base64);
}

//set variables
var d = new Date;
var expiration = 3600; // 1 hour,
var unixtime = parseInt(d.getTime() / 1000);
var future_unixtime = unixtime + expiration;
var	publicKey = "your_public_key";
var	privateKey = "your_private_key";
var	method = "PUT";
var route = "entries/29";

stringToSign = publicKey + ":" + method + ":" + route + ":" + future_unixtime;
sig = CalculateSig(stringToSign, privateKey);
var url = 'http://localhost/wp.dev/gravityformsapi/' + route + '?api_key=' + publicKey + '&signature=' + sig + '&expires=' + future_unixtime;

var update_entry = {
	form_id     : '1',
	date_created: '2016-07-29 21:38:23',
	is_starred  : 0,
	is_read     : 1,
	ip          : '::1',
	source_url  : 'http://localhost/wpdev/?gf_page=preview&id=1',
	currency    : 'USD',
	created_by  : 1,
	user_agent  : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0',
	status      : 'active',
	2.3         : 'Testing',
	2.6         : 'Tester',
	1           : 'xxxxxxxxxxxxx'
} ;

entry_json = JSON.stringify( update_entry );

$.ajax({
	url: url,
	type: 'PUT',
	data: entry_json,
	contentType:'application/json',
	success: function(result) {alert('success');},
	error: function(result, textStatus, errorThrown){alert('error ' + errorThrown);}
});

If the update were successful, the result will look similar to the following:

 {"status":200,"response":"Entry updated successfully"}

PUT /entries

Updates the entries sent in the body

  • URI: /gravityformsapi/entries
  • Capability: gravityforms_edit_entries
  • Input: A JSON string with a collection of entries. Please see the Entry Object for more details regarding what may be included.
  • Output: A localized message describing the result: “Entries updated successfully”
  • Potential Errors:
    If the entry id provided cannot be found, a not_found error code is returned:

     {"status":404,"response":{"code":"not_found","message":"Entry with id 1000 not found","data":"1000"}}

    If an invalid form id is provided when updating the entry, an invalid_form_id error code is returned:

    {"status":400,"response":{"code":"invalid_form_id","message":"The form for this entry does not exist"}}

If there is a problem updating the entry in the database, the following message is displayed, along with the applicable SQL error, if one exists.

{"status":error code,"response":{"code":"update_entry_properties_failed","message":"There was a problem while updating the entry properties","data":"sql statement"}
If there is a problem updating the value for a field which has inputs, the following message is displayed, along with the applicable SQL error, if one exists.
{"status":error code,"response":{"code":"update_input_value_failed","message":"There was a problem while updating one of the input values for the entry","data":"sql statement"}
If there is a problem updating the value for a field, the following message is displayed, along with the applicable SQL error, if one exists.
{"status":error code,"response":{"code":"update_field_values_failed","message":"There was a problem while updating the field values","data":"sql statement"}
  • Notes: If an error is encountered updating an entry, the error information is returned, and no further entries are updated.
    If values are not provided for the following entry fields, default values are used:

    • date_created – utc_timestamp()
    • is_starred – 0
    • is_read – 0
    • ip – $_SERVER
    • source_url – http://$_SERVER[‘HTTP_HOST’] . $_SERVER[‘REQUEST_URI’] (If $_SERVER[‘HTTPS’] or force ssl is on, then https is used)
    • user_agent – API
    • status – active
    • currency – USD
  • Examples:
    The example below has two entries in a manually created array. Each entry is an array, and those entries are placed into one array. This array is then JSON-encoded so it may be passed to the API.

PHP

//set API keys
$api_key = 'your_api_key';
$private_key = 'your_private_key';

//set route
$route = 'entries';

//creating request URL
$expires = strtotime( '+60 mins' );
$string_to_sign = sprintf( '%s:%s:%s:%s', $api_key, 'PUT', $route, $expires );
$sig = calculate_signature( $string_to_sign, $private_key );
$url = 'http://localhost/wp/gravityformsapi/' . $route . '?api_key=' . $api_key . '&signature=' . $sig . '&expires=' . $expires;

$entries = array(
	array(
		'id'           => 156,
		'form_id'      => '28',
		'date_created' => '2015-06-15 22:43:23',
		'is_starred'   => 0,
		'is_read'      => 1,
		'ip'           => '::1',
		'source_url'   => 'http://localhost/wp/?gf_page=preview&id=28',
		'currency'     => 'USD',
		'created_by'   => 1,
		'user_agent'   => 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0',
		'status'       => 'active',
		'1.3'          => 'Ellen',
		'1.6'          => 'Ripley',
		'2'            => 'aliens',
		'3'            => 'Sigourney Weaver',
	),
	array(
		'id'           => 157,
		'form_id'      => '28',
		'date_created' => '2015-06-15 22:43:23',
		'is_starred'   => 0,
		'is_read'      => 1,
		'ip'           => '::1',
		'source_url'   => 'http://localhost/wp/?gf_page=preview&id=28',
		'currency'     => 'USD',
		'created_by'   => 1,
		'user_agent'   => 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0',
		'status'       => 'active',
		'1.3'          => 'Eric',
		'1.6'          => 'Draven',
		'2'            => 'brandonlee',
		'3'            => 'The Crow',
	),
);

//json encode array
$entry_json = json_encode( $entries );

//retrieve data
$response = wp_remote_request( urlencode( $url ), array( 'method' => 'PUT', 'body' => $entry_json ) );
if ( wp_remote_retrieve_response_code( $response ) != 200 || ( empty( wp_remote_retrieve_body( $response ) ) ) ){
	//http request failed
	die( 'There was an error attempting to access the API.' );
}

//result is in the response "body" and is json encoded.
$body = json_decode( wp_remote_retrieve_body( $response ), true );

if( $body['status'] > 202 ){
	$error = $body['response'];

        //entry update failed, get error information, error could just be a string
	if ( is_array( $error )){
		$error_code 	= $error['code'];
		$error_message 	= $error['message'];
		$error_data 	= isset( $error['data'] ) ? $error['data'] : '';
		$status 	= "Code: {$error_code}. Message: {$error_message}. Data: {$error_data}.";
	}
	else{
		$status = $error;
	}
	die( "Could not post entries. {$status}" );
}

function calculate_signature( $string, $private_key ) {
	$hash = hash_hmac( 'sha1', $string, $private_key, true );
	$sig = rawurlencode( base64_encode( $hash ) );
	return $sig;
}

JavaScript
WARNING: This sample JavaScript is not secure and it’s not intended to be used on production sites. Never send your private key to the browser. Consider using WordPress cookie authentication instead.

<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/hmac-sha1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/enc-base64-min.js"></script>
<script type="text/javascript">
function CalculateSig(stringToSign, privateKey){
	//calculate the signature needed for authentication
	var hash = CryptoJS.HmacSHA1(stringToSign, privateKey);
	var base64 = hash.toString(CryptoJS.enc.Base64);
	return encodeURIComponent(base64);
}

//set variables
var d = new Date;
var expiration = 3600; // 1 hour,
var unixtime = parseInt(d.getTime() / 1000);
var future_unixtime = unixtime + expiration;
var	publicKey = "your_public_key";
var	privateKey = "your_private_key";
var	method = "PUT";
var route = "entries";

stringToSign = publicKey + ":" + method + ":" + route + ":" + future_unixtime;
sig = CalculateSig(stringToSign, privateKey);
var url = 'http://localhost/wp.dev/gravityformsapi/' + route + '?api_key=' + publicKey + '&signature=' + sig + '&expires=' + future_unixtime;

var update_entries = [
	{
		id	    : '7',
		form_id     : '1',
		date_created: '2016-07-29 21:38:23',
		is_starred  : 0,
		is_read     : 1,
		ip          : '::1',
		source_url  : 'http://localhost/wp.dev/?gf_page=preview&id=1',
		currency    : 'USD',
		created_by  : 1,
		user_agent  : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0',
		status      : 'active',
		2.3         : 'Gravity',
		2.6         : 'Forms',
		1           : 'X'
	},
	{
		id	    : '16',
		form_id     : '1',
		date_created: '2016-07-29 21:38:23',
		is_starred  : 0,
		is_read     : 1,
		ip          : '::1',
		source_url  : 'http://localhost/wpdev/?gf_page=preview&id=1',
		currency    : 'USD',
		created_by  : 1,
		user_agent  : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0',
		status      : 'active',
		2.3         : 'Rocket',
		2.6         : 'Genius',
		1           : 'gravity'
	}
];

entry_json = JSON.stringify( update_entries );

$.ajax({
	url: url,
	type: 'PUT',
	data: entry_json,
	contentType:'application/json',
	success: function(result) {alert('success');},
	error: function(result, textStatus, errorThrown){alert('error ' + errorThrown);}
});
</script>

DELETE /entries/[Entry ID]

Deletes the entry or entries with the specified ID or IDs. The deletion process completely removes the entry; it will NOT be available in the Trash.

  • URI: /gravityformsapi/entries/[Entry ID]
    //delete a single entry
    http://[your_domain]/gravityformsapi/entries/1
    
    //delete multiple entries
    http://[your_domain]/gravityformsapi/entries/1;3;6
    
  • Capability: gravityforms_delete_entries
  • Output: A localized message describing the result: “Entries deleted successfully”
  • Potential Errors:
    If an entry being deleted cannot be found, and invalid_entry_id code is returned.

     {"status":400,"response":{"code":"invalid_entry_id","message":"Invalid entry id: 164","data":"164"}}
  • Notes: If an error is encountered while deleting one of the entries in a list of multiple entries, the error information is returned, and no further entries are deleted.
  • Example:
    The example below deletes the entries with ids 164, 165, 166.

PHP

//set API keys
$api_key = 'your_api_key';
$private_key = 'your_private_key';

//set route
$route = 'entries/164;165;166';

//creating request URL
$expires = strtotime( '+60 mins' );
$string_to_sign = sprintf( '%s:%s:%s:%s', $api_key, 'DELETE', $route, $expires );
$sig = calculate_signature( $string_to_sign, $private_key );
$url = 'http://localhost/wp/gravityformsapi/' . $route . '?api_key=' . $api_key . '&signature=' . $sig . '&expires=' . $expires;

//retrieve data
$response = wp_remote_request( urlencode( $url ), array( 'method' => 'DELETE' ) );
if ( wp_remote_retrieve_response_code( $response ) != 200 || ( empty( wp_remote_retrieve_body( $response ) ) ) ){
	//http request failed
	die( 'There was an error attempting to access the API.' );
}

//result is in the response "body" and is json encoded.
$body = json_decode( wp_remote_retrieve_body( $response ), true );

if( $body['status'] > 202 ){
	$error = $body['response'];

        //entry update failed, get error information, error could just be a string
	if ( is_array( $error )){
		$error_code 	= $error['code'];
		$error_message 	= $error['message'];
		$error_data 	= isset( $error['data'] ) ? $error['data'] : '';
		$status 	= "Code: {$error_code}. Message: {$error_message}. Data: {$error_data}.";
	}
	else{
		$status = $error;
	}
}
else{
    //entries deleted successfully
    $status  = $status_code;
}

die( "Entry deletion status: {$status}" );

function calculate_signature( $string, $private_key ) {
	$hash = hash_hmac( 'sha1', $string, $private_key, true );
	$sig = rawurlencode( base64_encode( $hash ) );
	return $sig;
}

JavaScript
WARNING: This sample JavaScript is not secure and it’s not intended to be used on production sites. Never send your private key to the browser. Consider using WordPress cookie authentication instead.

<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/hmac-sha1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/enc-base64-min.js"></script>
<script type="text/javascript">
function CalculateSig(stringToSign, privateKey){
	//calculate the signature needed for authentication
	var hash = CryptoJS.HmacSHA1(stringToSign, privateKey);
	var base64 = hash.toString(CryptoJS.enc.Base64);
	return encodeURIComponent(base64);
}

//set variables
var d = new Date;
var expiration = 3600; // 1 hour,
var unixtime = parseInt(d.getTime() / 1000);
var future_unixtime = unixtime + expiration;
var	publicKey = "your_public_key";
var	privateKey = "your_private_key";
var	method = "DELETE";
var route = "entries/164;165;166";

stringToSign = publicKey + ":" + method + ":" + route + ":" + future_unixtime;
sig = CalculateSig(stringToSign, privateKey);
var url = 'http://localhost/wp.dev/gravityformsapi/' + route + '?api_key=' + publicKey + '&signature=' + sig + '&expires=' + future_unixtime;

$.ajax({
	url: url,
	type: 'DELETE',
	contentType:'application/json',
	success: function(result) {document.write(result.response);},
	error: function(result, textStatus, errorThrown){alert('error ' + errorThrown);}
});
</script>

If the deletion is successful, the response will look like the following:

{"status":200,"response":"Entries deleted successfully: 3"}

Results

GET /forms/[Form ID]/results

Returns the aggregate results (entry counts) for each of the fields in the given form.

If the results take longer than approximately 20 seconds to complete, then the calculation process will stop and the incomplete results will be returned with a status code of 202 (accepted).
The calculation will continue in the background using a recursive wp_cron task with breaks of ten seconds until it finishes. When the calculation is complete, the results will be returned with a status code of 200 (OK).

If the background task for a request stops for more than 3 minutes (e.g. system restart, script timeout or memory issues) it will be rescheduled the next time the server is polled for the same request.

After an entry has been created the status of the results will change to “expired” and the new calculation of the results will begin again in the background.

When the fields have been edited using the form editor all cached results for that form will be deleted.

Editing form settings will not affect the cached results.

  • URI: /gravityformsapi/forms/[Form ID]/results
  • Capability: gravityforms_view_entries
  • Output: A JSON string containing the results data plus the following where appropriate:
    • status = “incomplete”, “complete” or “expired”
    • timestamp = [UTC UNIX timestamp for the calculation]
    • progress = [percentage of results calculated so far]
    • offset = [number of entries processed so far]
  • Potential Errors:
    • If the form id specified cannot be found, a “Not found” message is returned.
      {"status":404,"response":"Not found"}
  • Example:
    The example below retrieves the results for form id 3 which has two text fields. The count of how many times each field has been filled out is returned.

PHP

//set API keys
$api_key = 'your_api_key';
$private_key = 'your_private_key';

//set route
$route = 'forms/3/results';

//creating request URL
$expires = strtotime( '+60 mins' );
$string_to_sign = sprintf( '%s:%s:%s:%s', $api_key, 'GET', $route, $expires );
$sig = calculate_signature( $string_to_sign, $private_key );
$url = 'http://localhost/wp/gravityformsapi/' . $route . '?api_key=' . $api_key . '&signature=' . $sig . '&expires=' . $expires;

//retrieve data
$response = wp_remote_request( urlencode( $url ), array( 'method' => 'GET' ) );
if ( wp_remote_retrieve_response_code( $response ) != 200 || ( empty( wp_remote_retrieve_body( $response ) ) ) ){
	//http request failed
	die( 'There was an error attempting to access the API.' );
}

//result is in the response "body" and is json encoded.
$body = json_decode( wp_remote_retrieve_body( $response ), true );

if( $body['status'] > 202 ){
	$error = $body['response'];

	if ( is_array( $error ) ) {
		//get error information
		$error_code 	= $error['code'];
		$error_message 	= $error['message'];
		$error_data 	= isset( $error['data'] ) ? $error['data'] : '';
		$status 	    = "Code: {$error_code}. Message: {$error_message}. Data: {$error_data}.";
		die( "Could not retrieve results. {$status}" );
	}
	else{
		die( $error );
	}
}
else{
	$response = $body['response'];
	$entry_count = $response['entry_count'];
	$field_data = $response['field_data'];
	$retrieval_status = $response['status'];
	$timestamp = $response['timestamp'];
	foreach ( $field_data as $id=>$data ){
		echo 'Field: ' . $id . ' Count: ' . $data;
	}
}

JavaScript
WARNING: This sample JavaScript is not secure and it’s not intended to be used on production sites. Never send your private key to the browser. Consider using WordPress cookie authentication instead.

<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/hmac-sha1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/enc-base64-min.js"></script>
<script type="text/javascript">
function CalculateSig(stringToSign, privateKey){
	//calculate the signature needed for authentication
	var hash = CryptoJS.HmacSHA1(stringToSign, privateKey);
	var base64 = hash.toString(CryptoJS.enc.Base64);
	return encodeURIComponent(base64);
}

//set variables
var d = new Date;
var expiration = 3600; // 1 hour,
var unixtime = parseInt(d.getTime() / 1000);
var future_unixtime = unixtime + expiration;
var	publicKey = "your_public_key";
var	privateKey = "your_private_key";
var	method = "GET";
var route = "forms/1/results";

stringToSign = publicKey + ":" + method + ":" + route + ":" + future_unixtime;
sig = CalculateSig(stringToSign, privateKey);
var url = 'http://localhost/wp.dev/gravityformsapi/' + route + '?api_key=' + publicKey + '&signature=' + sig + '&expires=' + future_unixtime;

$.get(url, function(data, textStatus)
{
	//get the data from the api
	if ( data.status != 200 || ( typeof( data ) != 'object' ) ) {
		//http request failed
		document.write( 'There was an error attempting to access the API - ' + data.status + ': ' + data.response );
		return;
	}
	response    = data.response;
	entry_count = response.entry_count
	field_data = response.field_data;
});
</script>

Sample JSON output from the code above:

{"status":200,"response":{"entry_count":"3","field_data":{"1":4,"2":2},"status":"complete","timestamp":1448490482}}

Tools

Sample REST API v1 Client

A sample add-on using the REST API v1 is available on GitHub:

https://github.com/rocketgenius/webapiclient

PHP Wrapper

The PHP wrapper itself can be found inside the includes folder of the sample REST API v1 client add-on:

https://github.com/rocketgenius/webapiclient/blob/master/includes/class-gf-web-api-wrapper.php

Please take a look at both the inline documentation and the sample REST API v1 client add-on for examples of how to use it.

URL generator & tester

On the REST API v1 settings tab you’ll find a link to the developer tools. The tools include a URL generator and a URL tester. These will help you generate the correct signatures so you can check you’re generating the correct URLs.

Other resources

Tutorial on the Gravity Forms API

Go package for Gravity Forms REST API v1 (3rd Party Resource)
Note that this is not maintained by or affiliated with Gravity Forms or Rocketgenius. Not officially supported. Use at your own risk.