FacetWP has two API endpoints: the /facetwp/v1/fetch and the /facetwp/v1/refresh endpoint. The /facetwp/v1/fetch endpoint lets you query raw FacetWP data, with which you can build custom applications. The /facetwp/v1/refresh endpoint is used by FacetWP itself in the front-end, for filtering.

By default, the /facetwp/v1/fetch endpoint is disabled, to protect your data. To use it, you need to enable it.

The /facetwp/v1/refresh endpoint is always open. If you want to protect this endpoint (and with that, facet filtering) from being accessed by non-logged-in users, see the section below.

Enable the fetch API endpoint

By default, the /facetwp/v1/fetch API endpoint is disabled. To enable it, use this hook in your (child) theme’s functions.php:

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

add_filter( 'facetwp_api_can_access', function( $boolean ) { return current_user_can( 'manage_options' ); });

Fetch endpoint URL

/wp-json/facetwp/v1/fetch

The /facetwp/v1/fetch endpoint expects a POST request with 1 parameter: data. This parameter should be a string (a stringified JSON object).

Example

Let’s retrieve cars with make = audi, and also grab choices for the vehicle_type facet.

Here’s the request JSON, before getting stringified:

How to use custom JavaScript code?

JavaScript code can be placed in your (child) theme's main JavaScript file. Alternatively, you can add it manually between <script> tags in the <head> section of your (child) theme's header.php file. You can also load it with a hook in your (child) theme's functions.php file, or in the Custom Hooks add-on. To load the code only on pages with facets, use the facetwp_scripts hook. To load it on all pages, use wp_head or wp_footer. Or you can use a code snippets plugin. More info

var request_data = { 'data': { 'facets': { 'make': ['audi'], 'vehicle_type': [] }, 'query_args': { 'post_type': 'cars', 'posts_per_page': 4, 'paged': 1 } } };

Here’s the request using JavaScript’s fetch() method:

How to use custom JavaScript code?

JavaScript code can be placed in your (child) theme's main JavaScript file. Alternatively, you can add it manually between <script> tags in the <head> section of your (child) theme's header.php file. You can also load it with a hook in your (child) theme's functions.php file, or in the Custom Hooks add-on. To load the code only on pages with facets, use the facetwp_scripts hook. To load it on all pages, use wp_head or wp_footer. Or you can use a code snippets plugin. More info

var response = fetch('https://yoursite.com/wp-json/facetwp/v1/fetch', { 'method': 'POST', 'headers': { 'Content-Type': 'application/json', 'Authorization': 'Basic ' + btoa('username:password') // base64-encoded }, 'body': JSON.stringify(request_data) }) .then(response => response.json()) .then(result => console.log(result));

Response data

{ "results":[ 1, 2, 3, 4 ], "facets":{ "make":{ "name":"make", "label":"Make", "type":"checkboxes", "selected":[ "audi" ], "choices":[ { "value":"audi", "label":"Audi", "depth":0, "count":20 } ] }, "vehicle_type":{ "name":"vehicle_type", "label":"Vehicle Type", "type":"checkboxes", "selected":[ ], "choices":[ { "value":"car", "label":"Car", "depth":0, "count":17 }, { "value":"suv", "label":"SUV", "depth":0, "count":3 }, { "value":"minivan", "label":"Minivan", "depth":0, "count":0 }, { "value":"truck", "label":"Truck", "depth":0, "count":0 }, { "value":"van", "label":"Van", "depth":0, "count":0 } ] } }, "pager":{ "page":1, "per_page":4, "total_rows":20, "total_pages":5 } }

Restrict the REST API (and facet filtering) to authenticated users

By default, the /facetwp/v1/fetch endpoint is closed, unless enabled. But the /facetwp/v1/refresh endpoint is always open, because it is used by FacetWP itself in the front-end, for filtering.

If you have facet pages that are only available to logged-in users, you may want to prevent non-logged-in users from accessing the /facetwp/v1/refresh endpoint entirely. To do this, you could use a plugin like WordPress Rest API Authentication by miniOrange. The paid version of this plugin lets you protect selected endpoints of third-party plugins (like FacetWP).

You could also protect the whole WordPress REST API. Note that is not advisable to disable the WordPress REST API, because doing so will break WordPress Admin functionality that depends on the API being active. But you can require authentication for all WordPress REST API requests, effectively protecting the entire API from anonymous external access.

To do so, you can add the following code to your (child) theme’s functions.php, as advised in the WordPress REST API handbook:

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

// Source: // https://developer.wordpress.org/rest-api/frequently-asked-questions/ add_filter( 'rest_authentication_errors', function( $result ) { // If a previous authentication check was applied, // pass that result along without modification. if ( true === $result || is_wp_error( $result ) ) { return $result; } // No authentication has been performed yet. // Return an error if user is not logged in. if ( ! is_user_logged_in() ) { return new WP_Error( 'rest_not_logged_in', __( 'You are not currently logged in.' ), array( 'status' => 401 ) ); } // Our custom authentication check should have no effect // on logged-in requests return $result; });

Note that with the above code in place, also FacetWP’s /facetwp/v1/refresh endpoint will be blocked from non-logged-in users. You’ll notice that facet filtering will now no longer work, also not for logged-in users, because by default, the WordPress REST API doesn’t pass along authentication data. To fix this, you need to add a second piece of code, as explained in this tutorial on how to pass authentication data through REST API requests.

Fix refresh issues when using user authentication

By default, the WordPress REST API doesn’t pass along authentication data. So if your FacetWP template or custom code depends on the currently logged-in user (e.g. with is_user_logged_in()), or if you restrict WordPress REST API access to logged-in users, you will run into issues with your code not working after an AJAX refresh is triggered (which happens when using facets). See this tutorial on how to pass authentication data through REST API requests.

Trigger the indexer programmatically

You may need to trigger the indexer programmatically if posts aren’t saved via the normal /wp-admin/.

The second code sample on the above-linked section shows how to force FacetWP to re-index a specific post.

See also

Last updated: July 29, 2024