REST API v2 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:

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.

Gravity Forms REST API Add Key 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.

WordPress 5.6 Application Passwords

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://docs.gravityforms.com/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:

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 signature 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.