REST API v2 Guide

REST API v2 Guide

IntroductionUpgrading to Version 2AuthenticationSpecify the Content Type when appropriateExampleNo Response EnvelopeExampleForm SubmissionsExamplePOST Single ResourcesDELETE now trashesDELETE, POST and PUT responsesUnit TestsAPI DocumentationAuthenticationAPI PathSending RequestsPHPEndpointsGET /entriesPathResponse [json]Example ResponseRequired PropertiesOptional PropertiesSample UsageRetrieve specific fieldsInclude field labelsInclude specific formsInclude specific entriesUse PagingUse SortingSearchPOST /entriesPathInput [json]Example InputResponse [json]Example ResponseRequired PropertiesOptional PropertiesPayment PropertiesGET /entries/[ENTRY_ID]PathResponse [json]Response ExampleRequired PropertiesOptional PropertiesPUT /entries/[ENTRY_ID]PathInput [json]Example InputResponse [json]Example ResponseRequired PropertiesOptional PropertiesPayment PropertiesPOST /entries/[ENTRY_ID]/notificationsPathResponseRequired PropertiesOptional PropertiesSample UsageDELETE /entries/[ENTRY_ID]PathResponse [json]Successful ResponseFailed ResponseEntry Already Deleted ResponseRequired PropertiesOptional PropertiesGET /formsPathResponse [json]Required PropertiesOptional PropertiesSample UsagePOST /formsPathInputExample InputResponseSuccessful ResponseFailed ResponseRequired PropertiesPUT /forms/[FORM_ID]PathInputExample InputResponseSuccessful ResponseFailed ResponseRequired PropertiesDELETE /forms/[FORM_ID]PathResponseSuccessfully Deleted ResponseAttempt to Delete Trashed Form ResponseForce Delete ResponseFailed ResponseRequired PropertiesOptional PropertiesGET /forms/[FORM_ID]PathResponseSuccessful ResponseForm Not Found ResponseGET /forms/[FORM_ID]/entriesPathResponse [json]Example ResponseNo Entries Found ResponseOptional ArgumentsSample UsagePOST /forms/[FORM_ID]/entriesPathInput [json]Example InputResponse [json]Required PropertiesOptional PropertiesPayment PropertiesGET /forms/[FORM_ID]/resultsPathResponseRequired PropertiesOptional PropertiesSample UsagePOST /forms/[FORM_ID]/submissionsPathInputResponseRequired PropertiesOptional Properties

Notice: This article refers to version 2 of the Gravity Forms REST API, released as part of Gravity Forms core in Fall 2018.
Introduction
The REST API v2 add-on (which was released as a beta initially back in late 2016) was incorporated into Gravity Forms core from Gravity Forms 2.4, released in the Fall of 2018. The original Web API functionality supported by previous releases of Gravity Forms is now renamed to REST API Version 1. This document describes some of the changes between the two API versions as well as a full description on all REST API Version 2 endpoints.
If you need information on version 1 of the REST API, see the REST API v1 documentation
Upgrading to Version 2
The API is intended to feel as familiar as possible to developers who have worked with the WordPress REST API while
maintaining as much functionality as possible as version 1. The endpoints are largely the same as version 1, however,
the responses are slightly different and authentication has changed.
The following breaking changes are required by clients to consume version 2:
Authentication
The REST API version 2 now supports Basic Authentication as well as OAuth 1.0a Authentication. In order to use the new version 2 endpoints, users will first need to create API Keys on the REST API setting page, then configure Basic or OAuth 1.0a Authentication. For more information, see the Authentication section below.
Specify the Content Type when appropriate
The content-type application/json must be specified when sending JSON.
Example
curl --data [EXAMPLE_DATA] --header "Content-Type: application/json" https://localhost/wp-json/gf/v2

No Response Envelope
The response will not be enveloped by default. This means that the response will not be a JSON string containing the
「status」 and 「response」 – the body will contain the response and the HTTP code will contain the status.
The WP-API will envelope the response if the _envelope param is included in the request.
Example
Standard response:
{
"3": "Drop Down First Choice",
"created_by": "1",
"currency": "USD",
"date_created": "2016-10-10 18:06:12",
"form_id": "1",
"id": "1",
"ip": "127.0.0.1",
"is_fulfilled": null,
"is_read": 0,
"is_starred": 0,
"payment_amount": null,
"payment_date": null,
"payment_method": null,
"payment_status": null,
"post_id": null,
"source_url": "http://localhost?gf_page=preview&id=1",
"status": "active",
"transaction_id": null,
"transaction_type": null,
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36"
}

Response with _envelope parameter:
{
"body": {
"3": "Drop Down First Choice",
"created_by": "1",
"currency": "USD",
"date_created": "2016-10-10 18:06:12",
"form_id": "1",
"id": "1",
"ip": "127.0.0.1",
"is_fulfilled": null,
"is_read": 0,
"is_starred": 0,
"payment_amount": null,
"payment_date": null,
"payment_method": null,
"payment_status": null,
"post_id": null,
"source_url": "http://localhost?gf_page=preview&id=1",
"status": "active",
"transaction_id": null,
"transaction_type": null,
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36"
},
"headers": {
"Allow": "GET, POST, PUT, PATCH, DELETE"
},
"status": 200
}

Form Submissions
The Form Submissions endpoint now accepts application/json, application/x-www-form-urlencoded and multipart/form-data
content types. With the introduction of support for multipart/form-data now files can be sent to single file upload fields.
Request values should be sent all together instead of in separate elements for input_values, field_values, target_page
and source_page.
Example
Example body of a JSON request:
{
"input_1": "test",
"field_values": "",
"source_page": 1,
"target_page": 0
}

POST Single Resources
In order to maintain consistency with the WP API, the POST /entries and POST /forms endpoints no longer accept
collections. This means that it』s no longer possible to create multiple entries or forms in a single request.
DELETE now trashes
Sending DELETE requests will send the resource to the trash instead of deleting it permanently.
Repeating the DELETE request will not delete the resource permanently but it will generate a 401 (Gone) response code.
Use the 『force』 parameter to delete the entry or form permanently.
DELETE, POST and PUT responses
Successful DELETE, POST and PUT requests now return the deleted, updated or created entry or form instead of a confirmation message.
Unit Tests
The unit tests can be installed from the terminal using:
bash tests/bin/install.sh [DB_NAME] [DB_USER] [DB_PASSWORD] [DB_HOST]

If you』re using VVV you can use this command:
bash tests/bin/install.sh wordpress_unit_tests root root localhost

API Documentation
Authentication
See the Rest API V2 Authentication article.
API Path
The API can be accessed as route from the WordPress REST API. This should look something like this:
https://localhost/wp-json/gf/v2/
For example, to obtain the Gravity Forms entry with ID 5, your request would be made to the following:
https://localhost/wp-json/gf/v2/entries/5
Sending Requests
PHP
// Define the URL that will be accessed.
$url = rest_url( 'gf/v2/entries' );

// Example using Basic Authentication
$args = array(
'Authorization' => 'Basic ' . base64_encode( 'admin' . ':' . '12345' ),
'headers' => array( 'Content-type' => 'application/json' ),
);

// Make the request to the API.
$response = wp_remote_get( $url, $args );

// Check the response code.
if ( wp_remote_retrieve_response_code( $response ) != 200 || ( empty( wp_remote_retrieve_body( $response ) ) ) ){
// If not a 200, 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 );

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

// Entries retrieved successfully.
$entries = $body['response'];

In this example, the $entries variable contains the response from the API request.
Endpoints
GET /entries
Gets all entries.
Path
https://localhost/wp-json/gf/v2/entries
Response [json]
The response will contain a JSON object which contains the entry details. An example can be found below:
Example Response
{
"total_count": 2,
"entries": [
{
"2": "Creating using REST API v2",
"3": "Manually created using the POST route of the REST API v2",
"id": "311",
"form_id": "176",
"post_id": null,
"date_created": "2018-10-16 12:43:23",
"date_updated": "2018-10-16 19:33:56",
"is_starred": "0",
"is_read": "1",
"ip": "::1",
"source_url": "http://localhost/wp.dev/?gf_page=preview&id=176",
"user_agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0",
"currency": "USD",
"payment_status": null,
"payment_date": null,
"payment_amount": null,
"payment_method": "",
"transaction_id": null,
"is_fulfilled": null,
"created_by": "1",
"transaction_type": null,
"status": "active",
"1.3": "Post",
"1.6": "Entries 2",
"1.2": "",
"1.4": "",
"1.8": "",
"_labels": {
"1": {
"1.2": "Prefix",
"1.3": "First",
"1.4": "Middle",
"1.6": "Last",
"1.8": "Suffix"
},
"2": "Untitled",
"3": "Untitled"
}
},
{
"2": "Creating using REST API v2",
"3": "Manually created using the POST route of the REST API v2",
"id": "310",
"form_id": "176",
"post_id": null,
"date_created": "2018-10-16 12:43:23",
"date_updated": "2018-10-16 19:32:16",
"is_starred": "0",
"is_read": "1",
"ip": "::1",
"source_url": "http://localhost/wp.dev/?gf_page=preview&id=176",
"user_agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0",
"currency": "USD",
"payment_status": null,
"payment_date": null,
"payment_amount": null,
"payment_method": "",
"transaction_id": null,
"is_fulfilled": null,
"created_by": "1",
"transaction_type": null,
"status": "active",
"1.3": "Post",
"1.6": "Entries 1",
"1.2": "",
"1.4": "",
"1.8": "",
"_labels": {
"1": {
"1.2": "Prefix",
"1.3": "First",
"1.4": "Middle",
"1.6": "Last",
"1.8": "Suffix"
},
"2": "Untitled",
"3": "Untitled"
}
}
]
}

Required Properties
There are no required properties.
Optional Properties

_field_ids – A comma separated list of fields to include in the response.
_labels – Enables the inclusion of field labels in the results. Use the value 「1」 to include labels.
form_ids – An array of forms to include in the response.
include – An array of entries to include in the response. If an entry id included is not found in the database, no error is thrown.
paging – The paging criteria.
The paging encompasses the following:
        page_size – The number of results per page.
        current_page – The current page from which to pull details.
        offset – The record number on which to start retrieving data. It is zero-based. If the current_page property is specified, then offset is not used.
search – The search criteria.
The search encompasses the following:
        status – The status of the entry. Possible values are active, spam, trash.
        The default status is active.
        mode – The type of search to apply. Possible values are all, any. The default mode is all.
        field_filters – An array of filters to search by. The array uses:
                key – The field ID.
                value – The value to search for.
                operator – The comparison operator to use. The operator defaults to =.
                Possible values are: is, =, contains, like, is not, isnot, <>, not in, in.
sorting – The sorting criteria. The default sort is by entry id, descending (most recent entries first).
The sorting encompasses the following:
        key – The database field by which to sort. See the database structure for the wp_gf_entry table for fields that may be used.
        direction – The direction. Either ASC, DESC, or RAND (random order).
        is_numeric – If the key is numeric.

Sample Usage
Retrieve specific fields
//retrieve field ids 1, 6.1, 6.2, 6.3 and date_created for entry id 5
https://localhost/wp-json/gf/v2/entries/5?_field_ids=1,6.1,6.2,6.3,date_created

Include field labels
//include field labels in results
https://localhost/wp-json/gf/v2/entries?_labels=1

Include specific forms
//retrieve data for form id 1 and form id 30
//each form id needs to be represented as an array
//the first form is listed as form_ids[0], next forms_id[1], then forms_id[2]
https://localhost/wp-json/gf/v2/entries?form_ids[0]=1&form_ids[1]=30

Include specific entries
//retrieve data for entry id 1 and entry id 3
//each entry id needs to be represented as an array
//the first entry is listed as include[0], next include[1], then include[2]
https://localhost/wp-json/gf/v2/entries?include[0]=1&include[1]=3

Use Paging
//retrieve 20 results per page
https://localhost/wp-json/gf/v2/entries?paging[page_size]=20

//retrieve 20 results per page starting with the 16th row (offset starts at 0)
https://localhost/wp-json/gf/v2/entries?paging[page_size]=20&paging[offset]=15

//retrieve 5 results per page, starting with the second page
https://localhost/wp-json/gf/v2/entries?paging[page_size]=5&paging[current_page]=2

Use Sorting
//sort results ASCending by id
https://localhost/wp-json/gf/v2/entries?sorting[key]=id&sorting[direction]=ASC&sorting[is_numeric]=true

//sort results DESCending by date_created
https://localhost/wp-json/gf/v2/entries?sorting[key]=date_created&sorting[direction]=DESC&sorting

//sort results randomly
https://localhost/wp-json/gf/v2/entries?sorting[direction]=RAND

//sort results by post_id
https://localhost/wp-json/gf/v2/entries?sorting[key]=post_id

//sort results by field id 2
https://localhost/wp-json/gf/v2/entries?sorting[key]=2

Search
//retrieve entries where field id 2 contains the text **test**
https://localhost/wp-json/gf/v2/entries/?search={"field_filters": [{"key":2,"value":"test","operator":"contains"}]}

//retrieve entries where field id 2 AND field id 1.3 contains the text **squiffy**
//since the search mode is not specified **and** is used for the mode
https://localhost/wp-json/gf/v2/entries?search={"field_filters": [{"key":2,"value":"squiffy","operator":"contains"},{"key":1.3,"value":"squiffy","operator":"contains"}]}

//same search but setting mode to **any**
https://localhost/wp-json/gf/v2/entries?search={"field_filters":{"mode":"any","0":{"key":2,"value":"squiffy","operator":"contains"},"1":{"key":1.3,"value":"squiffy","operator":"contains"}}}

//retrieve entries created on a specific day (use the date_created field)
//this example returns entries created on September 10, 2019
https://localhost/wp-json/gf/v2/entries?search={"field_filters": [{"key":"date_created","value":"09/10/2019","operator":"is"}]}

POST /entries
Creates a single entry.
Path
https://localhost/wp-json/gf/v2/entries
Input [json]
The data sent must be in JSON format.
Example Input
{
"form_id" :"176",
"date_created" :"2018-10-16 12:43:23",
"is_starred" :0,
"is_read" :1,
"ip" :"::1",
"source_url" :"http://localhost/wp.dev/?gf_page=preview&id=176",
"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" :"Post",
"1.6" :"Entries 2",
"2" :"Creating using REST API v2",
"3" :"Manually created using the POST route of the REST API v2"
}

Response [json]
When creating an entry, the response body will contain the newly created entry.
Example Response
{
"2": "Creating using REST API v2",
"3": "Manually created using the POST route of the REST API v2",
"form_id": 176,
"date_created": "2018-10-16 12:43:23",
"is_starred": 0,
"is_read": 1,
"ip": "::1",
"source_url": "http://localhost/wp.dev/?gf_page=preview&id=176",
"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": "Post",
"1.6": "Entries 2",
"id": 313
}

Required Properties

form_id – The ID of the form to which the entry belongs.

Optional Properties

created_by – The user ID of the entry submitter.
date_created – The date the entry was created, in UTC.
ip – The IP address of the entry creator.
is_fulfilled – Whether the transaction has been fulfilled, if applicable.
is_read – Whether the entry has been read.
is_starred – Whether the entry is starred.
source_url – The URL where the form was embedded.
status – The status of the entry.
user_agent – The user agent string for the browser used to submit the entry.

Payment Properties
Payment properties only apply when payment fields are present.

payment_amount – The amount of the payment.
payment_date – The date of the payment.
payment_method – The payment method for the payment.
payment_status – The status of the payment.
transaction_id – The transaction ID for the payment.
transaction_type – The type of the transaction.

GET /entries/[ENTRY_ID]
Gets an entry based on the entry ID.
Path
https://localhost/wp-json/gf/v2/entries/1
Response [json]
The response will contain a JSON object with the entry details.
Response Example
{
"id": "71",
"form_id": "1",
"date_created": "2016-11-28 18:12:17",
"is_starred": 0,
"is_read": 0,
"ip": "127.0.0.1",
"source_url": "http://localhost/pagename",
"post_id": null,
"created_by": "2",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.87 Safari/537.36",
"status": "active",
"1": "",
"2": "",
"3": "",
"4": "",
"5": "",
"6.1": "",
"6.2": "",
"6.3": ""
}

Required Properties
There are no required properties.
Optional Properties

_field_ids – A comma separated list of fields to include in the response.
_labels – Enables the inclusion of field labels in the results. Use the value 「1」 to include labels.

PUT /entries/[ENTRY_ID]
Updates an entry based on the specified entry ID.
Path
https://localhost/wp-json/gf/v2/entries/1
Input [json]
The data sent must be in JSON format.
Example Input
{
"form_id" :"176",
"date_created" :"2018-10-16 12:43:23",
"is_starred" :1,
"is_read" :1,
"ip" :"::1",
"source_url" :"http://localhost/wp.dev/?gf_page=preview&id=176",
"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" :"Test Put",
"1.6" :"Update Entry 312",
"2" :"Creating using REST API v2",
"3" :"Manually created using the POST route of the REST API v2"
}

Response [json]
When updating an entry, the response body will contain the complete updated entry.
Example Response
{
"2": "Creating using REST API v2",
"3": "Manually created using the POST route of the REST API v2",
"id": "313",
"form_id": "176",
"post_id": null,
"date_created": "2018-10-16 12:43:23",
"date_updated": "2018-10-16 21:13:37",
"is_starred": "1",
"is_read": "1",
"ip": "::1",
"source_url": "http://localhost/wp.dev/?gf_page=preview&id=176",
"user_agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0",
"currency": "USD",
"payment_status": null,
"payment_date": null,
"payment_amount": null,
"payment_method": "",
"transaction_id": null,
"is_fulfilled": null,
"created_by": "1",
"transaction_type": null,
"status": "active",
"1.3": "Test Put",
"1.6": "Update Entry 312",
"1.2": "",
"1.4": "",
"1.8": ""
}

Required Properties
There are no required properties, but values not provided WILL BE BLANKED OUT.
Optional Properties

created_by – The user ID of the entry submitter.
date_created – The date the entry was created, in UTC.
ip – The IP address of the entry creator.
is_fulfilled – Whether the transaction has been fulfilled, if applicable.
is_read – Whether the entry has been read.
is_starred – Whether the entry is starred.
source_url – The URL where the form was embedded.
status – The status of the entry.
user_agent – The user agent string for the browser used to submit the entry.

Payment Properties
Payment properties only apply when payment fields are present.

payment_amount – The amount of the payment.
payment_date – The date of the payment.
payment_method – The payment method for the payment.
payment_status – The status of the payment.
transaction_id – The transaction ID for the payment.
transaction_type – The type of the transaction.

POST /entries/[ENTRY_ID]/notifications
Sends the notifications for the given entry.
Path
https://localhost/wp-json/gf/v2/entries/1/notifications
Response
If successful, an array of the notification ids processed is returned.
[
"5bc65eb299da8",
"5bc63abd9601a"
]

Required Properties
There are no required properties
Optional Properties

_notifications – Comma-separated list of notification ids to be sent for the entry.
_event – The event to trigger. The default is 「form_submission」.

Sample Usage
https://localhost/wp-json/gf/v2/entries/1/notifications?_notifications=5bc65eb299da8,5bc63abd9601a

https://localhost/wp-json/gf/v2/entries/1/notifications?_event=form_submission

DELETE /entries/[ENTRY_ID]
Sends the specified entry to the trash. If the entry is already in the trash then repeating this request will not delete the entry permanently but the response code will be 410 (Gone). Use the 『force』 parameter to delete the entry permanently.
Path
https://localhost/wp-json/gf/v2/entries/1
https://localhost/wp-json/gf/v2/entries/1?force=1

Response [json]
Successful Response
A successful response will return a JSON string of the trashed or deleted entry.
{
"2": "x",
"3": "x",
"id": "314",
"form_id": "176",
"post_id": null,
"date_created": "2018-10-16 21:57:28",
"date_updated": "2018-10-16 21:57:28",
"is_starred": "0",
"is_read": "0",
"ip": "::1",
"source_url": "http://localhost/wp.dev/?gf_page=preview&id=176",
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36",
"currency": "USD",
"payment_status": null,
"payment_date": null,
"payment_amount": null,
"payment_method": null,
"transaction_id": null,
"is_fulfilled": null,
"created_by": "1",
"transaction_type": null,
"status": "trash",
"1.3": "test",
"1.6": "test",
"1.2": "",
"1.4": "",
"1.8": ""
}

Failed Response
A failed response will provide a JSON string of the error code and message.
{
"code": "gf_cannot_delete",
"message": "Invalid entry id: 71",
"data": {
"status": 500
}
}

Entry Already Deleted Response
{
"code": "gf_already_trashed",
"message": "The entry has already been deleted.",
"data": {
"status": 410
}
}

Required Properties
There are no required properties.
Optional Properties

force – Deletes the entry permanently when setting to 「1」.

GET /forms
Gets the details of all forms.
Path
https://localhost/wp-json/gf/v2/forms
Response [json]
{
"4": {
"id": "4",
"title": "Multi-Page Form",
"entries": "2"
},
"1": {
"id": "1",
"title": "Test Form",
"entries": "60"
},
"5": {
"id": "5",
"title": "Test Form 2",
"entries": "2"
},
"6": {
"id": "6",
"title": "Test Form 3",
"entries": "2"
}
}

Required Properties
There are no required properties.
Optional Properties

include – An array of forms to include in the response.

Sample Usage
https://localhost/wp-json/gf/v2/forms?include[1]&include[3]

POST /forms
Creates a form.
Path
https://localhost/wp-json/gf/v2/forms
Input
The information for the new form will be in a JSON string.
Example Input
{
"title":"API Generated Form",
"description":"This is the description for the form generated by the API",
"labelPlacement":"top_label",
"button":{
"type":"text",
"text":"",
"imageUrl":""
},
"fields":[
{
"id" : "1",
"label" : "My Text",
"type" : "text"
},
{
"id" : "2",
"label" : "More Text",
"type" : "text"
}
],
"confirmations":{
"0":
{
"id" : 0,
"name" : "Default Confirmation",
"type" : "redirect",
"url" : "http://www.rocketgenius.com",
"isDefault" : true
},
"1":
{
"id" : 1,
"name" : "Confirmation 2",
"type" : "message",
"message" : "Thanks for contacting us! We will get in touch with you shortly.",
"isDefault" : false
}
}
}

Response
Successful Response
A successful response returns a JSON string of the newly created form.
{
"title":"API Generated Form(2)",
"description":"This is the description for the form generated by the API",
"labelPlacement":"top_label",
"button":{
"type":"text",
"text":"",
"imageUrl":""
},
"fields":[
{
"type":"text","id":1,
"label":"My Text",
"visibility":"visible",
"pageNumber":1,
"formId":179,
"adminLabel":"",
"description":"",
"isRequired":false,
"allowsPrepopulate":false,
"inputMask":false,
"inputMaskValue":"",
"inputType":"",
"size":"",
"errorMessage":"",
"labelPlacement":"",
"descriptionPlacement":"",
"subLabelPlacement":"",
"placeholder":"",
"cssClass":"",
"inputName":"",
"noDuplicates":false,
"defaultValue":"",
"inputs":"",
"choices":"",
"conditionalLogic":""
},
{
"type":"text",
"id":2,
"label":"More Text",
"visibility":"visible",
"pageNumber":1,
"formId":179,
"adminLabel":"",
"description":"",
"isRequired":false,
"allowsPrepopulate":false,
"inputMask":false,
"inputMaskValue":"",
"inputType":"",
"size":"",
"errorMessage":"",
"labelPlacement":"",
"descriptionPlacement":"",
"subLabelPlacement":"",
"placeholder":"",
"cssClass":"",
"inputName":"",
"noDuplicates":false,
"defaultValue":"",
"inputs":"",
"choices":"",
"conditionalLogic":""
}
],
"version":"2.3.4.3",
"id":179,
"notifications":[],
"confirmations":[
{
"id":0,
"name":"Default Confirmation",
"type":"redirect",
"url":"http://www.rocketgenius.com",
"isDefault":true
},
{
"id":1,
"name":"Confirmation 2",
"type":"message",
"message":"Thanks for contacting us! We will get in touch with you shortly.",
"isDefault":false
}
],
"is_active":"1",
"date_created":"2018-10-18 20:18:43",
"is_trash":"0"
}

Failed Response
The failed response will be a JSON string with the code and message.
{
"code": "missing_form_json",
"message": "The Form object must be sent as a JSON string in the request body with the content-type header set to application/json.",
"data": {
"status": 400
}
}

Required Properties

fields – A collection of Field Objects. See the example input above for how to format this.
title – The form title.

PUT /forms/[FORM_ID]
Updates a form.
Path
https://localhost/wp-json/gf/v2/forms
Input
The form information will be sent in a JSON string.
Example Input
{
"title":"My Form Updated Using PUT",
"description":"This is the description for the form generated by the API",
"labelPlacement":"top_label",
"button":{
"type":"text",
"text":"",
"imageUrl":""
},
"fields":[
{
"id" : "1",
"label" : "My Text",
"type" : "text"
},
{
"id" : "2",
"label" : "More Text",
"type" : "text"
}
]
}

Response
Successful Response
A successful response returns a JSON string of the updated form.
{
"title": "My Form Created by POSTing",
"description": "This is the description for the form generated by the API",
"labelPlacement": "top_label",
"button": {
"type": "text",
"text": "",
"imageUrl": ""
},
"fields": [
{
"type": "text",
"id": 1,
"label": "My Text",
"visibility": "visible",
"pageNumber": 1,
"fields": "",
"formId": "184",
"adminLabel": "",
"description": "",
"isRequired": false,
"allowsPrepopulate": false,
"inputMask": false,
"inputMaskValue": "",
"inputType": "",
"size": "",
"errorMessage": "",
"labelPlacement": "",
"descriptionPlacement": "",
"subLabelPlacement": "",
"placeholder": "",
"cssClass": "",
"inputName": "",
"noDuplicates": false,
"defaultValue": "",
"inputs": "",
"choices": "",
"conditionalLogic": ""
},
{
"type": "text",
"id": 2,
"label": "More Text",
"visibility": "visible",
"pageNumber": 1,
"fields": "",
"formId": "184",
"adminLabel": "",
"description": "",
"isRequired": false,
"allowsPrepopulate": false,
"inputMask": false,
"inputMaskValue": "",
"inputType": "",
"size": "",
"errorMessage": "",
"labelPlacement": "",
"descriptionPlacement": "",
"subLabelPlacement": "",
"placeholder": "",
"cssClass": "",
"inputName": "",
"noDuplicates": false,
"defaultValue": "",
"inputs": "",
"choices": "",
"conditionalLogic": ""
}
],
"version": "2.4-beta-1",
"id": "184",
"notifications": [],
"confirmations": [
{
"id": 0,
"name": "Default Confirmation",
"type": "redirect",
"url": "http://www.rocketgenius.com",
"isDefault": true
},
{
"id": 1,
"name": "Confirmation 2",
"type": "message",
"message": "Thanks for contacting us! We will get in touch with you shortly.",
"isDefault": false
}
],
"is_active": "0",
"date_created": "2018-10-22 22:08:08",
"is_trash": "0"
}

Failed Response
The failed response will be a JSON string with the code and message.
Form Not Found
{
"code": "not_found",
"message": "Form not found",
"data": {
"status": 404
}
}

Bad JSON string
{
"code": "missing_form_json",
"message": "The Form object must be sent as a JSON string in the request body with the content-type header set to application/json.",
"data": {
"status": 400
}
}

Required Properties

title – The form title.
NOTE: The title will be removed if you do not include it in the string.
fields – A collection of Field Objects. See the example input above for how to format this.
NOTE: If you do NOT include the fields collection, the form fields will be removed!

DELETE /forms/[FORM_ID]
Sends the specified form to the trash. If the form is already in the trash, then repeating this request will not delete
the form permanently, but the response code will be 410 (Gone). Use the force parameter to delete the form permanently.
Path
https://localhost/wp-json/gf/v2/forms/1
Response
Successfully Deleted Response
A successful response returns the deleted form. Notice the is_trash value is set to 「1」, meaning the form is no longer active and is in the Trash.
{
"title": "My Form Updated",
"labelPlacement": "top_label",
"fields": [
{
"type": "text",
"id": 1,
"label": "My Text",
"visibility": "visible",
"pageNumber": 1,
"fields": "",
"formId": "183",
"adminLabel": "",
"description": "",
"isRequired": false,
"allowsPrepopulate": false,
"inputMask": false,
"inputMaskValue": "",
"inputType": "",
"size": "",
"errorMessage": "",
"labelPlacement": "",
"descriptionPlacement": "",
"subLabelPlacement": "",
"placeholder": "",
"cssClass": "",
"inputName": "",
"noDuplicates": false,
"defaultValue": "",
"inputs": "",
"choices": "",
"conditionalLogic": ""
}
],
"version": "2.4-beta-1",
"id": "183",
"notifications": [],
"confirmations": [
{
"id": 0,
"name": "Default Confirmation",
"type": "redirect",
"url": "http://www.rocketgenius.com",
"isDefault": true
},
{
"id": 1,
"name": "Confirmation xxxxx",
"type": "message",
"message": "Thanks for contacting us! We will get in touch with you shortly.",
"isDefault": false,
"disableAutoformat": false,
"pageId": 0,
"url": "",
"queryString": "",
"conditionalLogic": {
"actionType": "show",
"logicType": "all",
"rules": [
{
"fieldId": "1",
"operator": "is",
"value": ""
}
]
}
}
],
"is_active": "0",
"date_created": "2018-10-22 21:39:12",
"is_trash": "1"
}

Attempt to Delete Trashed Form Response
{
"code": "gf_already_trashed",
"message": "The form has already been deleted.",
"data": {
"status": 410
}
}

Force Delete Response
Notice the deleted value of true in the response. The entire Form Object is also placed as the value for previous.
{
"deleted": true,
"previous": {
"title": "My Form Updated",
"labelPlacement": "top_label",
"fields": [
{
"type": "text",
"id": 1,
"label": "My Text",
"visibility": "visible",
"pageNumber": 1,
"fields": "",
"formId": "183",
"adminLabel": "",
"description": "",
"isRequired": false,
"allowsPrepopulate": false,
"inputMask": false,
"inputMaskValue": "",
"inputType": "",
"size": "",
"errorMessage": "",
"labelPlacement": "",
"descriptionPlacement": "",
"subLabelPlacement": "",
"placeholder": "",
"cssClass": "",
"inputName": "",
"noDuplicates": false,
"defaultValue": "",
"inputs": "",
"choices": "",
"conditionalLogic": ""
}
],
"version": "2.4-beta-1",
"id": "183",
"notifications": [],
"confirmations": [
{
"id": 0,
"name": "Default Confirmation",
"type": "redirect",
"url": "http://www.rocketgenius.com",
"isDefault": true
},
{
"id": 1,
"name": "Confirmation xxxxx",
"type": "message",
"message": "Thanks for contacting us! We will get in touch with you shortly.",
"isDefault": false,
"disableAutoformat": false,
"pageId": 0,
"url": "",
"queryString": "",
"conditionalLogic": {
"actionType": "show",
"logicType": "all",
"rules": [
{
"fieldId": "1",
"operator": "is",
"value": ""
}
]
}
}
],
"is_active": "0",
"date_created": "2018-10-22 21:39:12",
"is_trash": "1"
}
}

Failed Response
{
"code": "gf_form_invalid_id",
"message": "Invalid form id.",
"data": {
"status": 404
}
}

Required Properties
There are no required properties.
Optional Properties

force – Deletes the form permanently when setting to 「1」, instead of moving to the Trash.

GET /forms/[FORM_ID]
Gets the details of a form based on the specified form ID.
Path
https://localhost/wp-json/gf/v2/forms/185
Response
Successful Response
The Form Object is returned.
{
"title": "Simple Form",
"description": "",
"labelPlacement": "top_label",
"descriptionPlacement": "below",
"button": {
"type": "text",
"text": "Submit",
"imageUrl": ""
},
"fields": [
{
"type": "text",
"id": 1,
"label": "Test",
"adminLabel": "",
"isRequired": false,
"size": "medium",
"errorMessage": "",
"visibility": "visible",
"inputs": null,
"formId": 185,
"description": "",
"allowsPrepopulate": false,
"inputMask": false,
"inputMaskValue": "",
"inputType": "",
"labelPlacement": "",
"descriptionPlacement": "",
"subLabelPlacement": "",
"placeholder": "",
"cssClass": "",
"inputName": "",
"noDuplicates": false,
"defaultValue": "",
"choices": "",
"conditionalLogic": "",
"productField": "",
"enablePasswordInput": "",
"maxLength": "",
"multipleFiles": false,
"maxFiles": "",
"calculationFormula": "",
"calculationRounding": "",
"enableCalculation": "",
"disableQuantity": false,
"displayAllCategories": false,
"useRichTextEditor": false,
"pageNumber": 1,
"fields": ""
}
],
"version": "2.4-beta-1",
"id": 185,
"useCurrentUserAsAuthor": true,
"postContentTemplateEnabled": false,
"postTitleTemplateEnabled": false,
"postTitleTemplate": "",
"postContentTemplate": "",
"lastPageButton": null,
"pagination": null,
"firstPageCssClass": null,
"nextFieldId": 2,
"notifications": {
"5bcf58ccf39c8": {
"id": "5bcf58ccf39c8",
"to": "{admin_email}",
"name": "Admin Notification",
"event": "form_submission",
"toType": "email",
"subject": "New submission from {form_title}",
"message": "{all_fields}"
}
},
"confirmations": {
"5bcf58cd012e7": {
"id": "5bcf58cd012e7",
"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": "2018-10-23 17:22:20",
"is_trash": "0"
}

Form Not Found Response
{
"code": "gf_not_found",
"message": "Form not found",
"data": null
}

GET /forms/[FORM_ID]/entries
Gets entries associated with a specific form.
Path
https://localhost/wp-json/gf/v2/forms/185/entries
Response [json]
The response will contain a JSON object which contains the details for each entry, along with a total_count of how many entries were returned.
Example Response
{
"total_count": 2,
"entries": [
{
"1": "Test 2",
"id": "318",
"form_id": "185",
"post_id": null,
"date_created": "2018-10-23 17:29:47",
"date_updated": "2018-10-23 17:29:47",
"is_starred": "0",
"is_read": "0",
"ip": "::1",
"source_url": "https://localhost/wp.dev/?gf_page=preview&id=185",
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36",
"currency": "USD",
"payment_status": null,
"payment_date": null,
"payment_amount": null,
"payment_method": null,
"transaction_id": null,
"is_fulfilled": null,
"created_by": "1",
"transaction_type": null,
"status": "active",
"3.2": "",
"3.3": "",
"3.4": "",
"3.6": "",
"3.8": ""
},
{
"1": "Test",
"id": "317",
"form_id": "185",
"post_id": null,
"date_created": "2018-10-23 17:29:38",
"date_updated": "2018-10-23 17:29:38",
"is_starred": "0",
"is_read": "0",
"ip": "::1",
"source_url": "https://localhost/wp.dev/?gf_page=preview&id=185",
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36",
"currency": "USD",
"payment_status": null,
"payment_date": null,
"payment_amount": null,
"payment_method": null,
"transaction_id": null,
"is_fulfilled": null,
"created_by": "1",
"transaction_type": null,
"status": "active",
"3.2": "",
"3.3": "",
"3.4": "",
"3.6": "",
"3.8": ""
}
],
"_labels": {
"1": "Test",
"3": {
"3": "Name",
"3.2": "Prefix",
"3.3": "First",
"3.4": "Middle",
"3.6": "Last",
"3.8": "Suffix"
}
}
}

No Entries Found Response
{
"total_count": 0,
"entries": []
}

Optional Arguments

_field_ids – A comma separated list of fields to include in the response.
_labels – Enables the inclusion of field labels in the results. Use the value 「1」 to include labels.
paging – The paging criteria.
The paging encompasses the following:
        page_size – The number of results per page.
        current_page – The current page from which to pull details.
        offset – The offset to begin with.
search – The search criteria.
The search encompasses the following:
        field_filters – An array of filters to search by.
        key – The field ID.
        value – The value to search for.
        operator – The comparison operator to use.
sorting – The sorting criteria.
The sorting encompasses the following:
        key – The key by which to sort.
        direction – The direction. Either ASC or DESC.
        is_numeric – If the key is numeric.

Sample Usage
https://localhost/wp-json/gf/v2/forms/1/entries?_field_ids=1,6.1,6.2,6.3,date_created

https://localhost/wp-json/gf/v2/forms/1/entries?_labels=1

https://localhost/wp-json/gf/v2/forms/1/entries?paging[page_size]=20&paging[current_page]=2&paging[offset]=30

https://localhost/wp-json/gf/v2/forms/1/entries/?search={"field_filters": [{"key":2,"value":"test","operator":"contains"}]}

https://localhost/wp-json/gf/v2/forms/1/entries?sorting[key]=id&sorting[direction]=ASC&sorting[is_numeric]=true

POST /forms/[FORM_ID]/entries
Creates an entry based on the specified form ID.
Path
https://localhost/wp-json/gf/v2/forms/1/entries
Input [json]
The data sent must be in JSON format.
Example Input
{
"date_created" :"2018-10-16 12:43:23",
"is_starred" :0,
"is_read" :1,
"ip" :"::1",
"source_url" :"http://localhost/wp.dev/?gf_page=preview&id=176",
"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" :"POST using /forms/185/entries",
"3.3" :"API name",
"3.6" :"POST name"
}

Response [json]
The response body will contain the newly created entry.
{
"1": "POST using /forms/185/entries",
"date_created": "2018-10-16 12:43:23",
"is_starred": 0,
"is_read": 1,
"ip": "::1",
"source_url": "http://localhost/wp.dev/?gf_page=preview&id=176",
"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",
"3.3": "API name",
"3.6": "POST name",
"form_id": 185,
"id": 327
}

Required Properties
There are no required properties.
Optional Properties

created_by – The user ID of the entry submitter.
date_created – The date the entry was created, in UTC.
ip – The IP address of the entry creator.
is_fulfilled – Whether the transaction has been fulfilled, if applicable.
is_read – Whether the entry has been read.
is_starred – Whether the entry is starred.
source_url – The URL where the form was embedded.
status – The status of the entry.
user_agent – The user agent string for the browser used to submit the entry.

Payment Properties
Payment properties only apply when payment fields are present.

payment_amount – The amount of the payment.
payment_date – The date of the payment.
payment_method – The payment method for the payment.
payment_status – The status of the payment.
transaction_id – The transaction ID for the payment.
transaction_type – The type of the transaction.

GET /forms/[FORM_ID]/results
Gets form details, including entry details.
Returns the aggregate results (entry counts) for each of the fields in the given form.
Path
https://localhost/wp-json/gf/v2/forms/1/results
Response
{
"entry_count": 11,
"field_data": {
"1": 11,
"3": 10
},
"status": "complete",
"timestamp": 1540320989,
"labels": {
"1": "Test",
"3": "Name"
}
}

Required Properties
There are no required properties.
Optional Properties

search – The search criteria.
The search encompasses the following:
        field_filters – An array of filters to search by.
        key – The field ID.
        value – The value to search for.
        operator – The comparison operator to use.

Sample Usage

POST /forms/[FORM_ID]/submissions
Submits the specified form ID with the specified values.
Path
https://localhost/wp-json/gf/v2/forms/1/submissions
Input
The input is a JSON object containing each of the name-value pairs.
{
"input_1": "test",
"input_3_3" : "Rocket",
"input_3_6" : "Genius",
"field_values": "",
"source_page": 1,
"target_page": 0
}

Response
{
"is_valid":true,
"page_number":0,
"source_page_number":1,
"confirmation_message":"Thanks for contacting us! We will get in touch with you shortly.

",
"confirmation_type":"message"
}

Required Properties
input_[FIELD_ID] – The input values. Replace field ID with the input for which you want to submit data.
Optional Properties
field_values – The field values.
source_page – The source page number.
target_page – The target page number.

Details of the endpoints and methods for feeds can be found in the Managing Add-On Feeds With Rest API V2 article.

REST API v2 Authentication

REST API v2 Authentication

IntroductionAuthentication CredentialsGravity FormsWordPress Application PasswordsAuthentication MethodsBasic AuthenticationExamplesPostmanPHPOAuth 1.0a AuthenticationExamplesPostmanPHPWordPress AuthenticationTroubleshootingExample Logging StatementsSuccessful Basic Authentication using Gravity Forms CredentialsSuccessful Basic Authentication using WordPress Application PasswordSuccessful OAuth 1.0a AuthenticationOther Logging StatementsPossible Error Logging StatementsUnable to authenticate using Basic Authentication

REST API v2 Authentication
Introduction
The Gravity Forms REST API version 2 can be used to integrate Gravity Forms with custom apps, remote services, and other WordPress sites. Here are a few of the more common integrations we are aware of:

Zapier – documentation
Integromat – documentation
Automate.io – documentation
Zoho Flow – documentation

For authentication to succeed you must first ensure the REST API is enabled on the Forms > Settings > REST API page.
Authentication Credentials
Gravity Forms supports authenticating REST API requests using credentials created by Gravity Forms or WordPress.
Whichever credentials you choose to use please bear in mind that the Gravity Forms capabilities assigned to the user authenticating the request will be honored. For example, if the user does not have the capablility to edit entries (gravityforms_edit_entries), requests to update entries will fail. See the Role Management article for details about the available capabilities and how to manage them.
When creating your credentials, make sure to copy them as they will only be displayed once.
Gravity Forms
Credentials created by Gravity Forms can be used with both Basic Authentication and OAuth 1.0a Authentication methods. They can be created via the Forms > Settings > REST API page.
Click the 「Add Key」 button under the authentication section for version 2. You』ll be presented with the Add Key page:

a. Enter a friendly description for your API Key.
b. Select an existing WordPress user. This is the user whose account will be used to perform the requests.
c. Select the Permission level for this API Key. Note that in order for an API request to be successful, the user above must have the capabailities to do so, and the API Key permission must also allow it. For example, if you select 「Read」 permission for the API Key, all write requests to the REST API (i.e. edit entry, delete form, etc…) will be rejected even if the user configured above has the necessary capabilities to perform those actions.
d. Add Key to create your new key. The next page will display your Consumer Key & Secret Key.
NOTE: You will need to copy these keys down for your application as they will not be visible again once you leave this page.
When setting up Basic Authentication, use the Consumer Key as the username and Consumer Secret as the password.
WordPress Application Passwords
WordPress added support for Application Passwords in version 5.6. Starting with Gravity Forms 2.4.21.4 they can be used with the Basic Authentication method.
To create an Application Password with WordPress 5.6 or greater go to your profile page in the WordPress admin (/wp-admin/profile.php) and scroll towards the end of the page.

Enter a name in the 「New Application Password Name」 input and then click the 「Add New Application Password」 button. WordPress will generate and display the password which you can use to authenticate requests to the REST API.
When using this Application Password with Basic Authentication, use your account username or email address as the username.
Authentication Methods
Gravity Forms supports 2 built-in methods of authentication: Basic Authentication and OAuth 1.0a Authentication.
Basic Authentication
Basic Authentication is supported, but only on requests that are sent using HTTPS. HTTP requests must use OAuth 1.0a authentication.
Examples
Following are a few examples of requests with Basic Authentication:
Postman
Postman is a free app that allows you to easily send API requests without having to write any code. Download it here

PHP
$username = 'ck_c8d98772e0f4db070c97416796ff251fc991f454';
$password = 'cs_e0665f1acf0460581ab4fdce978404b28dab1a54';

$headers = array( 'Authorization' => 'Basic ' . base64_encode( "{$username}:{$password}" ) );
$response = wp_remote_get( 'https://gravityforms.local/wp-json/gf/v2/entries/5', array( 'headers' => $headers ) );

// Check the response code.
if ( wp_remote_retrieve_response_code( $response ) != 200 || ( empty( wp_remote_retrieve_body( $response ) ) ) ) {
// If not a 200, HTTP request failed.
die( 'There was an error attempting to access the API.' );
}

OAuth 1.0a Authentication
OAuth 1.0a is the recommended authentication method as it offers a higher level of security.
Note that array parameters must be indexed in order for the signature to validate correctly. For example use form_ids[0]=1&form_ids[1]=2 instead of form_ids[]=1&form_ids[]=2.
Examples
Following are a few examples of requests with OAuth 1.0a Authentication:
Postman
Postman is a free app that allows you to easily send API requests without having to write any code. Download it here

PHP
This example requires an OAuth helper class that can be downloaded here.
$consumer_key = 'ck_c8d98772e0f4db070c97416796ff251fc991f454';
$consumer_secret = 'cs_e0665f1acf0460581ab4fdce978404b28dab1a54';
$url = 'https://gravityforms.local/wp-json/gf/v2/forms';
$method = 'POST';
$args = array();

// Use helper to get oAuth authentication parameters in URL.
// Download helper library from: https://s22280.pcdn.co/wp-content/uploads/2017/01/class-oauth-request.php_.zip
require_once( 'class-oauth-request.php' );
$oauth = new OAuth_Request( $url, $consumer_key, $consumer_secret, $method, $args );

// Form to be created.
$form = array( 'title' => 'Form title' );

// Send request.
$response = wp_remote_request( $oauth->get_url(),
array(
'method' => $method,
'body' => json_encode( $form ),
'headers' => array( 'Content-type' => 'application/json' ),
)
);

// Check the response code.
if ( wp_remote_retrieve_response_code( $response ) != 200 || ( empty( wp_remote_retrieve_body( $response ) ) ) ) {
// If not a 200, HTTP request failed.
die( 'There was an error attempting to access the API.' );
}

WordPress Authentication
In addition to the authentication methods provided by Gravity Forms (described above), the REST API version 2 also supports any WordPress specific authentication, including cookie authentication and any of the authentication plugins. Here are some more information about those authentication methods:

WordPress REST API authentication documentation
WP REST API: Setting Up and Using Basic Authentication
WP REST API: Setting Up and Using OAuth 1.0a Authentication

Troubleshooting
Begin troubleshooting by:

Enable logging on the Forms > Settings page
On the Forms > Settings > Logging page, ensure that Gravity Forms API is enabled and set to log all messages.

Check our logging and debugging documentation for additional help.
As logging statements are only recorded when the functions they are contained within are run, perform the steps needed to replicate the issue such as connecting the integration or performing a request.
Example Logging Statements
Successful Basic Authentication using Gravity Forms Credentials

DEBUG –> GF_REST_Authentication::authenticate(): Running.
DEBUG –> GF_REST_Authentication::perform_basic_authentication(): Running.
DEBUG –> GF_REST_Authentication::perform_basic_authentication(): Valid.
DEBUG –> GF_REST_Authentication::check_user_permissions(): Running for user #1.
DEBUG –> GF_REST_Authentication::check_user_permissions(): Permissions valid.
DEBUG –> GF_REST_Controller::current_user_can_any(): method: GET; route: /gf/v2/forms; capability: 「gravityforms_edit_forms」; result: true.

Successful Basic Authentication using WordPress Application Password

DEBUG –> GF_REST_Authentication::authenticate(): Running.
DEBUG –> GF_REST_Authentication::perform_basic_authentication(): Running.
ERROR –> GF_REST_Authentication::perform_basic_authentication(): Aborting; user not found.
DEBUG –> GF_REST_Authentication::perform_application_password_authentication(): Running.
DEBUG –> GF_REST_Authentication::perform_application_password_authentication(): Valid.
DEBUG –> GF_REST_Authentication::check_user_permissions(): Running for user #1.
DEBUG –> GF_REST_Authentication::check_user_permissions(): Permissions valid.
DEBUG –> GF_REST_Controller::current_user_can_any(): method: GET; route: /gf/v2/forms; capability: 「gravityforms_edit_forms」; result: true.

Successful OAuth 1.0a Authentication

DEBUG –> GF_REST_Authentication::authenticate(): Running.
DEBUG –> GF_REST_Authentication::perform_basic_authentication(): Running.
ERROR –> GF_REST_Authentication::perform_basic_authentication(): Aborting; credentials not found.
DEBUG –> GF_REST_Authentication::perform_application_password_authentication(): Running.
ERROR –> GF_REST_Authentication::perform_application_password_authentication(): Aborting; user not found.
DEBUG –> GF_REST_Authentication::perform_oauth_authentication(): Running.
DEBUG –> GF_REST_Authentication::perform_oauth_authentication(): Valid.
DEBUG –> GF_REST_Authentication::check_user_permissions(): Running for user #1.
DEBUG –> GF_REST_Authentication::check_user_permissions(): Permissions valid.
DEBUG –> GF_REST_Controller::current_user_can_any(): method: GET; route: /gf/v2/forms; capability: 「gravityforms_edit_forms」; result: true.

Other Logging Statements

DEBUG –> GF_REST_Authentication::is_request_to_rest_api(): Executing functions hooked to gform_is_request_to_rest_api.
DEBUG –> GF_REST_Authentication::authentication_fallback(): Running.
DEBUG –> GF_REST_Authentication::authenticate(): User #1 already authenticated.

Possible Error Logging Statements

ERROR –> GF_REST_Authentication::perform_basic_authentication(): Aborting; credentials not found.

This is used when the username (consumer key) and/or password (consumer secret) are not found in the request.

ERROR –> GF_REST_Authentication::perform_basic_authentication(): Aborting; user not found.

This is used when credentials are found in the request but a user could not be found for the username (consumer key).

ERROR –> GF_REST_Authentication::set_error(): {「errors」:{「gform_rest_authentication_error」:[「Consumer secret is invalid.」]},」error_data」:{「gform_rest_authentication_error」:{「status」:401}}}

This is used when the basic auth username (consumer key) is valid and the password (consumer secret) is invalid.

ERROR –> GF_REST_Authentication::perform_application_password_authentication(): Aborting; user not found.

This is used when WordPress was not able to authenticate the request using an Application Password.

ERROR –> GF_REST_Authentication::set_error(): {「errors」:{「gform_rest_authentication_error」:[「Unknown email address. Check again or try your username.」]},」error_data」:{「gform_rest_authentication_error」:{「status」:401}}}

This is used when the WordPress Application Password validation fails.

ERROR –> GF_REST_Authentication::perform_oauth_authentication(): Aborting; OAuth parameters not found.

This is used when the OAuth parameters such as the consumer key, timestamp, nonce, signature, or singature method are not found in the request.

ERROR –> GF_REST_Authentication::set_error(): {「errors」:{「gform_rest_authentication_error」:[「Consumer key is invalid.」]},」error_data」:{「gform_rest_authentication_error」:{「status」:401}}}

This is used when a user could not be found for the consumer key included in the OAuth request.

ERROR –> GF_REST_Authentication::set_error(): {「errors」:{「gform_rest_authentication_error」:[「Invalid signature – failed to sort parameters.」]},」error_data」: {「gform_rest_authentication_error」:{「status」:401}}}

This is used when a user was found for the consumer key in the OAuth request but the request parameters could not be sorted into the correct order.

ERROR –> GF_REST_Authentication::set_error(): {「errors」:{「gform_rest_authentication_error」:[「Invalid signature – signature method is invalid.」]},」error_data」:{「gform_rest_authentication_error」:{「status」:401}}}

This is used when the OAuth request signature method is not HMAC-SHA1 or HMAC-SHA256.

ERROR –> GF_REST_Authentication::set_error(): {「errors」:{「gform_rest_authentication_error」:[「Invalid signature – provided signature does not match.」]},」error_data」:{「gform_rest_authentication_error」:{「status」:401}}}

This is used when the OAuth request signature does not match the expected signature for the request being performed.

ERROR –> GF_REST_Authentication::set_error(): {「errors」:{「gform_rest_authentication_error」:[「Invalid timestamp.」]},」error_data」:{「gform_rest_authentication_error」:{「status」:401}}}

This is used when the OAuth request timestamp does not match the current timestamp plus or minus a small window.

ERROR –> GF_REST_Authentication::set_error(): {「errors」:{「gform_rest_authentication_error」:[「Invalid nonce – nonce has already been used.」]},」error_data」:{「gform_rest_authentication_error」:{「status」:401}}}

This is used when the OAuth nonce has already been used by a previous request.

ERROR –> GF_REST_Authentication::set_error(): {「errors」:{「gform_rest_authentication_error」:[「The API key provided does not have read permissions.」]},」error_data」:{「gform_rest_authentication_error」:{「status」:401}}}

This is used when the Gravity Forms credentials are valid but the user does not have permission to perform GET or HEAD requests.

ERROR –> GF_REST_Authentication::set_error(): {「errors」:{「gform_rest_authentication_error」:[「The API key provided does not have write permissions.」]},」error_data」:{「gform_rest_authentication_error」:{「status」:401}}}

This is used when the Gravity Forms credentials are valid but the user does not have permission to perform POST, PUT, PATCH, or DELETE requests.

ERROR –> GF_REST_Authentication::set_error(): {「errors」:{「gform_rest_authentication_error」:[「Unknown request method.」]},」error_data」:{「gform_rest_authentication_error」:{「status」:401}}}

This is used when the Gravity Forms credentials are valid but an unknown request method is being used. Known request methods are HEAD, GET, POST, PUT, PATCH, DELETE, and OPTIONS.
Unable to authenticate using Basic Authentication
Some hosting environments, usually Apache based, aren』t configured to pass the basic authentication headers from incoming requests to PHP so they are not present when the WordPress and Gravity Forms APIs attempt to authenticate requests, which can result in authentication errors.
WordPress had a number of reports of issues like this during the development of their REST API. An engineer at WPEngine investigated and confirmed it is a hosting issue which hosts can resolve by making a change to the Apache configuration on the server hosting the site.
Please contact your web host and ask them to ensure the CGIPassAuth directive is enabled on the server hosting your site.
The WordPress REST API FAQ also includes additional solutions for this issue.

Rest API Change Log

Rest API Change Log

2.0-rc-22.0-rc-12.0-beta-22.0-beta-1

2.0-rc-2

Updated the POST /forms//entries endpoint to override the form_id entry property with the Form ID in the URL.
Updated the GET /forms//entries endpoint to return only active entries by default.

2.0-rc-1

Added the Location header when the confirmation is a redirect.
Added sanitization to the /forms endpoint.
Added the POST /entries//notifications endpoint which (re)sends notifications.
Added the _fields query param to the GET /entries, GET /entries/ and GET /forms//fields/ and GET /forms//entries//fields/ endpoints
Removed support for semicolon separated entry IDs in the GET /entries endpoint. Use the include query param instead.

2.0-beta-2

Added support for optional labels to the GET /entries endpoint.
Added support for entry trashing. Entries can only be deleted by sending the force param.
Added support for form trashing. Forms can only be deleted by sending the force param.
Changed the POST, PUT and DELETE endpoints for forms and entries to return the form/entry on success.
Fixed an issue with PUT /entries/[ID].
Removed the PUT /entries endpoint. Use PUT /entries/[ID] instead.
Removed authentication. Use WordPress REST API authentication instead.

2.0-beta-1

All new.

{rest_api_url} Merge Tag

{rest_api_url} Merge Tag

SummaryUsageNotes

Summary
Returns the REST API URL (e.g. https://your.domain/wp-json/).
Usage
Use {rest_api_url} in the Webhooks Add-On Request URL setting to populate that setting with the REST API URL when the feed is processed.
For example using {rest_api_url}wp/v2/posts in the Request URL setting would send the request to https://your.domain/wp-json/wp/v2/posts.
Notes
Available with the Webhooks Add-On (v1.1.5+).

Troubleshoot/Resolve Issues with Gravity Forms Entry Exports

Troubleshoot/Resolve Issues with Gravity Forms Entry Exports

Test for a conflictIncrease available PHP memoryIncrease the PHP max execution timeMake multiple smaller exportsCheck permissions and ownershipThe sanitize_file_name filter

At times, some users may experience issues when attempting to export entries. These issues are typically caused by theme/plugin conflicts or settings defined by the web host. In this article, we will provide a few possible solutions to this problem.
Test for a conflict
Entry exports use Ajax requests to get the fields for the selected form and then export the entries for the selected fields in batches. If there are any JavaScript errors present on the page due to a conflicting theme or plugin that can prevent the export from functioning correctly. You』ll want to perform a full theme and plugin conflict test.
Increase available PHP memory
Many times, the issue is caused by the maximum memory available to PHP scripts on your web hosts. With some hosts, you may be able to increase this on your own. While this can vary based on your specific web hosts, it usually involves editing a php.ini file as well as your wp-config.php file.
Increasing Your PHP Memory Limits
Increase the PHP max execution time
In addition to running out of available memory caused by large amounts of data being exported, it』s also possible that the export takes longer than allowed by PHP. When this occurs, the process stops running and the export will fail. One of the following may solve the problem for you.
Increasing Your PHP Max Execution Time
Make multiple smaller exports
Sometimes, the best solutions is to just export less data. The more data being exported, the more time and resources it is going to take to be able to process it. Selecting multiple smaller date ranges will allow you to export the same amount of data, but in smaller chunks at a time.
For more information on selecting date ranges in your entry exports, review our article on exporting form entries.
Check permissions and ownership
Gravity Forms will ask WordPress to use /wp-content/uploads/gravity_forms/export/ folder to generate your export file, if permissions or ownership of this folder is not correctly set to allow WordPress write files into it, the export will fail. Check the Troubleshooting and fixing 「Upload folder is not writable」 Errors doc page for more details.
The sanitize_file_name filter
In some cases usage of the WordPress sanitize_file_name filter in the theme or another plugin can cause an empty .csv file download. This usually happens when the filter is using the PHP uniqid() function to return a unique filename, this can result in the name of the temporary .csv file not matching the name the downloader is looking for.
You can prevent the filter overriding the csv export filename by including something like the following at the start of the function hooked to the filter.
function your_function_name( $filename ) {
if ( strpos( $filename, 'export-' ) !== false ) {
return $filename;
}
// override the filename

Resolving 「FAILED (Temporary file could not be moved)」 and 「Upload folder is not writable」 Errors

Resolving 「FAILED (Temporary file could not be moved)」 and 「Upload folder is not writable」 Errors

Check Folder PermissionsCheck Folder OwnershipCheck PHP SettingsEnsure File Isn』t Potentially DangerousEnable Logging

If you are getting an error when using Gravity Forms or the Dropbox add-on that says FAILED (Temporary file could not be moved), FAILED (upload folder could not be created), or Upload folder is not writable, there are a few different problems that could be the cause. Here are some troubleshooting steps that should help you track down the issue and solve the problem.
The information below is also applicable to log files not being created when logging is enabled.
Check Folder Permissions
Most often the error is caused by incorrect folder permissions within the wp-content/uploads directory. This is a standard WordPress upload path that will need to be writable before anything can be saved to it. Note that permissions can be different per folder, so you can have write permissions for the folder wp-content/uploads but not for wp-content/uploads/gravity_forms or a subdirectory of this.
To correct this, take a look at your file permissions on the server. Often times it』s as simple as setting the permissions correctly to 755 or 775, but this may vary based on your hosting environment. If you』re not sure how to change your file permissions or what your permissions should be, your web host will be able to point you in the right direction.
Check Folder Ownership
Another common cause for this error is the folder ownership. If the folder is not owned by the same user running the web server service, WordPress may be not able to perform write operations in the uploads folder. Changing the ownership of a folder can be done only by a server admin, so you will want to contact the web host and ask them to ensure WordPress is able to write under the path wp-content/uploads/gravity_forms and any folder below that path.
Check PHP Settings
While somewhat uncommon with modern web hosts, you might have Safe Mode enabled on your PHP configuration. To properly save content from WordPress and Gravity Forms, you』ll need to disable Safe Mode.
If you don』t know how to do this on your own, your best option is contacting your web host.
Ensure File Isn』t Potentially Dangerous
Many web hosts will block the upload of files that could be potentially dangerous such as .php files.
To allow these types of files, try including them within a zip file or contact your hosting provider for other possible solutions.
Enable Logging
Typically, a great deal of information can be exposed when using the Logging.
When looking through the logs, locate lines that contain GF_Field_FileUpload.

Resetting Results for Polls, Quizzes and Surveys

Resetting Results for Polls, Quizzes and Surveys

SummaryReset by Deleting EntriesReset by Deleting the FieldExample Animations

Summary

Results for Polls, Quizzes, and Surveys are calculated when needed using form entry data. This means to reset your results, you cannot just reset a counter, but you must delete the entry data associated with the fields of your Results type.

There are two primary ways to delete entry data: delete the whole entry, or by delete the field itself (along with all he associated data).

Reset by Deleting Entries

You can trash entries via the Entry detail page, or you can trash either individual entries, or entries in bulk, via the Entry list page. See the short animation at bottom.

Consider exporting your entries before deletion if you would like to keep a copy the existing data, just in case!

Reset by Deleting the Field

If you have a form that has field types that do not support results, (that you would like to keep), then deletions become more complicated. Instead of deleting the entries, we recommend editing the form to delete the fields of your Result type, i.e. Poll, Quiz, or Survey, which would then delete the entry data for those specific fields. The data from any other fields would remain intact. You can then rebuild the form by adding back the Poll fields as new.

Example Animations

Short animation showing the effect of bulk deleting entries on the Poll results.

Short animation showing the effect of deleting the poll field on the Poll results.

Resend Notifications

Resend Notifications

If you failed to receive a notification, Gravity Forms makes it easy to re-send that notification with just a few simple clicks. In this article, we will show you how to re-send a notification within Gravity Forms.

First, access your entries. To do so click on Forms on the left side navigation menu, hover over the form that you want to view the entries of, and click on Entries.You should now see a listing of all entries submitted through your form. Select the checkbox to the left of the entry, use the dropdown to select Resend Notifications, then click the Apply button.A window will now appear with notification options listed. Any notification that you have previously configured will appear here. Use these checkboxes select the notification type that you would like to send.Once your notification type is selected, an additional field will appear, allowing you to optionally override the email addresses within your selected notification type. If you would like to override the notification with different email addresses, simply place them within the Send To field in a comma-separated list.Once everything is set, go ahead and click the Resend Notifications button.

You can also access this option in Bulk Actions from the Entries List.

Requiring a Cardholder Name

Requiring a Cardholder Name

As some payment add-ons such as the Authorize.Net add-on do not require the cardholder name to be validated, it is not typically required within the credit card field. This snippet will allow you to require the cardholder』s name.
12345678add_filter( 'gform_field_validation', function ( $result, $value, $form, $field ) {    if ( $field->type == 'creditcard' && $result['is_valid'] && rgempty( $field->id . '.5', $value ) ) {        $result['is_valid'] = false;        $result['message']  = 'Please enter the cardholder first and last name.';    }     return $result;}, 10, 4 );

Repeater (beta)

Repeater (beta)

IntroductionAppearanceField PropertiesPermitted Sub-FieldsLabelMaximum Repeater ItemsButton TextRepeater Field NestingLimitationsEntriesExportSample FormsAll Supported FieldsNested RepeatersSample CodeExample 1Example 2Placement of the Repeater field within a form

Note: This field type, released with Gravity Forms 2.4, is currently in BETA. There is no Form Editor UI component built for this field yet. This means you cannot add this field to a form using standard Form Editor drag and drop methods. Currently this field is only intended for developers who can build their forms programmatically, or through other methods. Please open a support ticket if you are a developer who has run into trouble using this field.

Introduction

A repeater field is a collection of other Gravity Forms fields, combined together into a set that can then be used on a single form. The benefit is that when a user submits the form, the repeater field collection can be entered multiple times by the submitter, within the same single form submission.

Example: a repeater field for phone number, allowing a user to enter multiple country codes, phone numbers and associated phone number type data on a single contact form submission.Example: a repeater field consisting of attendee names and job titles, allowing a single convention registration form submission to include multiple people from the same organization.

Additionally, repeater fields can be nested within another repeater field. For example, you could allow multiple contact phone numbers to be entered for each attendee by combining the two examples mentioned above.

Save & Continue functionality is supported.

Appearance

Example of a Repeater field containing just one Name field.

Example with 3 nested Repeater fields.

Sub-fields are listed in the entry list filter so they can be searched like other fields on the form.

Field Properties

Permitted Sub-Fields

The fields property of the Repeater field is an array of fields (GF_Field objects). Supported field types are as follows:

Single Line Text; Paragraph Text; Drop Down; Multi Select; Number; Checkboxes; Radio Buttons; Name; Date; Time; Phone (「international」 format only); Address; Website; Email; List; Repeater (Nested).

Label

The value of the label property will be displayed at the top of the repeater field.

Maximum Repeater Items

The maximum number of items allowed in a repeater can be set using the maxItems field property (true/false).

Button Text

The button texts for adding and removing items for each repeater field can be defined with the field properties addButtonText and removeButtonText.

Repeater Field Nesting

A Repeater field can be nested inside another Repeater field.

There is no enforced limit to nesting depth, though form designers should consider the implications especially when designing for narrower screens.

Limitations

The following limitations exist for repeater fields as currently released. These items are likely to be addressed in future updates, so we recommend you monitor the latest releases to keep an eye on future improvements.

Conditional logic is not yet implemented.Calculations are not yet implemented.Re-ordering of items within the repeater field during form entry is not yet implemented.The rich text editor does not work within the paragraph field.The confirmation feature of the email field does not work.The 「Standard」 US format for the phone field does not work as expected.File Upload, Signature field, and Password field cannot be incorporated into a repeater fieldset.The CSS Ready classes will not work for fields inside the repeater.Dynamic population is not yet supported.Maintaining default values for the new items is not yet supported.Assigning unique tabindex attributes to new items is not yet supported. We recommend disabling the tabindex when embedding the form by using a value of 0.

Entries

All repeater field items will be displayed values that can be edited when the entry is edited.

To help with readability, the repeater field entry display uses indentation and line breaks to display the (possibly multiple) levels of input received in the single repeater field for an entry.

Export

The Conditional Logic setting for the entry export allows filtering by values of a Repeater』s sub-fields.

Note that indentations and line breaks will be present when you export the repeater data.

Sample Forms

All Supported Fields

All supported fields inside a repeater field:repeater-all-supported-fields.zip

Nested Repeaters

Three nested repeater fields:repeater-3-nested.zip

Sample Code

Example 1

How to add a Repeater field programmatically.

// Adjust your form ID
add_filter( 'gform_form_post_get_meta_149', 'add_my_field' );
function add_my_field( $form ) {

// Create a Single Line text field for the team member's name
$name = GF_Fields::create( array(
'type' => 'text',
'id' => 1002, // The Field ID must be unique on the form
'formId' => $form['id'],
'label' => 'Name',
'pageNumber' => 1, // Ensure this is correct
) );

// Create an email field for the team member's email address
$email = GF_Fields::create( array(
'type' => 'email',
'id' => 1001, // The Field ID must be unique on the form
'formId' => $form['id'],
'label' => 'Email',
'pageNumber' => 1, // Ensure this is correct
) );

// Create a repeater for the team members and add the name and email fields as the fields to display inside the repeater.
$team = GF_Fields::create( array(
'type' => 'repeater',
'description' => 'Maximum of 3 team members - set by the maxItems property',
'id' => 1000, // The Field ID must be unique on the form
'formId' => $form['id'],
'label' => 'Team Members',
'addButtonText' => 'Add team member', // Optional
'removeButtonText' => 'Remove team member', // Optional
'maxItems' => 3, // Optional
'pageNumber' => 1, // Ensure this is correct
'fields' => array( $name, $email ), // Add the fields here.
) );

$form['fields'][] = $team;

return $form;
}

// Remove the field before the form is saved. Adjust your form ID
add_filter( 'gform_form_update_meta_149', 'remove_my_field', 10, 3 );
function remove_my_field( $form_meta, $form_id, $meta_name ) {

if ( $meta_name == 'display_meta' ) {
// Remove the Repeater field: ID 1000
$form_meta['fields'] = wp_list_filter( $form_meta['fields'], array( 'id' => 1000 ), 'NOT' );
}

return $form_meta;
}

Example 2

This snippet grabs all the fields from another form, puts them into a single repeater field and adds the repeater to the form. Note that it may be necessary to set the pageNumber property.

// Adjust your form ID
add_filter( 'gform_form_post_get_meta_150', 'add_fields_from_another_form' );
function add_fields_from_another_form( $form ) {

$repeater = GF_Fields::create( array(
'type' => 'repeater',
'id' => 1000,
'formId' => $form['id'],
'label' => 'My Repeater',
'pageNumber' => 1, // Ensure this is correct
) );

$another_form = GFAPI::get_form( 103 );
foreach ( $another_form['fields'] as $field ) {
$field->id = $field->id + 1000;
$field->formId = $form['id'];
$field->pageNumber = 1; // Ensure this is correct

if ( is_array( $field->inputs ) ) {
foreach ( $field->inputs as &$input ) {
$input['id'] = (string) ( $input['id'] + 1000 );
}
}
}

$repeater->fields = $another_form['fields'];
$form['fields'][] = $repeater;

return $form;
}
// Remove the field before the form is saved. Adjust your form ID
add_filter( 'gform_form_update_meta_150', 'remove_my_field', 10, 3 );
function remove_my_field( $form_meta, $form_id, $meta_name ) {

if ( $meta_name == 'display_meta' ) {
// Remove the Repeater field: ID 1000
$form_meta['fields'] = wp_list_filter( $form_meta['fields'], array( 'id' => 1000 ), 'NOT' );
}

return $form_meta;
}

Placement of the Repeater field within a form

The placement of the repeater field in the form also needs to be controlled programmatically. Here is an example showing how you could insert the repeater field at a specific position in the fields array:

array_splice( $form['fields'], 2, 0, array( $repeater ) );

The fields array starts with an index of 0, using the above line which is adding the repeater field at index 2 would make the repeater field the third field on the form. You will need to determine what number you need to change the 2 in the example above to so that the repeater field falls between the range of fields in your form where you would like it to be located.