wordpress fetch data from api

If you work with WordPress and want to pull in data from external services or expose your own data via API, this article gives you the clarity and tools you need. You’ll learn how to fetch data from APIs in WordPress, how to display it, secure it, and optimise performance. 

In this article, you’ll gain a step-by‐step overview, sample code, best practices, and common pitfalls to avoid.

What “fetch data from API” means for WordPress

When you “fetch data from API” in WordPress, you are making HTTP requests either from your WordPress site to another service, or allowing other services to request data from your WordPress site. 

The most common scenario: you call an external API endpoint (for example, a weather service, stock prices, social feed) and you display that data in a WordPress theme, plugin, or block. Another scenario: you expose WordPress data (posts, pages, custom post types) to external consumers via the built-in REST interface.

Why you should fetch data via API in WordPress

There are several strong reasons:

  • You keep content dynamic and fresh without manual updates (e.g., live sports data, social feeds)

  • You integrate WordPress with external systems (CRM, analytics, mobile apps)

  • You enable headless or decoupled WordPress setups by exposing data via REST endpoints

  • You enhance user experience by loading data asynchronously, reducing full page loads

Getting started: understanding the WordPress REST API

WordPress includes a REST API by default (since version 4.7). You can access it via the URL your-site.com/wp-json/wp/v2/your-endpoint. This means you can fetch posts, pages, media, users, custom post types and more. With a simple GET request you return JSON data for consumption. You can filter, sort, and paginate the results using query parameters like ?per_page=10&page=2&orderby=date&order=desc.

When you register a custom post type you can make it available in the REST API by setting ‘show_in_rest’ => true and optionally define a custom rest_base. That lets external apps fetch that custom content easily.

How to fetch external API data in WordPress: PHP approach

If you want to call an external API from WordPress backend (plugins or theme functions), use WordPress HTTP API functions: wp_remote_get() or wp_remote_post().
Here is a simple example:

$response = wp_remote_get( ‘https://api.example.com/data’ );

if ( is_wp_error( $response ) ) {

    return;

}

$body = wp_remote_retrieve_body( $response );

$data = json_decode( $body, true );

// Now you can loop over $data and display or store it.

After retrieving the data, you might store it in an option or transient for caching (to avoid repeated API calls on every page load).

How to fetch data via JavaScript/AJAX in WordPress

If you need to fetch data dynamically on the front end, you can use JavaScript’s fetch() or use WordPress’s own library @wordpress/api-fetch. That package simplifies calls to WordPress REST endpoints.
Example:

import apiFetch from ‘@wordpress/api-fetch’;

apiFetch( { path: ‘/wp/v2/posts?per_page=5’ } ).then( posts => {

    console.log( posts );

} );

For external APIs you might use native fetch() like:

fetch( ‘https://api.example.com/data’ )

    .then( response => response.json() )

    .then( data => {

        // render data in DOM

    } );

Using JS lets you update parts of the page without full reload, improving UX.

Displaying fetched data in WordPress theme or block

Once you have the data, you’ll likely want to display it. You have options:

  • Use shortcode in PHP: you wrap logic in a function, return HTML, register via add_shortcode()

  • Add template logic in functions.php or theme file where you call fetching code and echo results

  • For block editor: create a custom block, use React/JS to fetch and render the data

For example, a simple shortcode could look like:

function my_api_shortcode() {

    $data = my_fetch_external_data();

    if ( empty( $data ) ) {

        return ”;

    }

    $html = ‘<ul>’;

    foreach ( $data as $item ) {

        $html .= ‘<li>’ . esc_html( $item[‘title’] ) . ‘</li>’;

    }

    $html .= ‘</ul>’;

    return $html;

}

add_shortcode( ‘external_list’, ‘my_api_shortcode’ );

Then you place [external_list] in a page or post.

Registering custom REST API endpoints in WordPress

Suppose you want to expose your own data for external use, you can register custom routes like:

add_action( ‘rest_api_init’, function () {

    register_rest_route( ‘myapp/v1’, ‘/latest-posts/(?P<cat_id>\d+)’, [

        ‘methods’             => ‘GET’,

        ‘callback’            => ‘get_latest_posts_by_category’,

        ‘permission_callback’ => function () {

            return current_user_can( ‘edit_posts’ );

        },

    ] );

} );

function get_latest_posts_by_category( $request ) {

    $cat_id = (int) $request[‘cat_id’];

    $query  = new WP_Query([

        ‘cat’       => $cat_id,

        ‘posts_per_page’ => 5,

    ]);

    $posts  = [];

    if ( $query->have_posts() ) {

        while ( $query->have_posts() ) {

            $query->the_post();

            $posts[] = [

                ‘id’    => get_the_ID(),

                ‘title’ => get_the_title(),

                ‘link’  => get_permalink(),

            ];

        }

        wp_reset_postdata();

    }

    return rest_ensure_response( $posts );

}

This gives external apps a JSON feed specific to your custom route.

Authentication and security when fetching/serving data

If your API fetch involves protected content (for example, private posts, user data) or you expose endpoints that mutate data, you must secure access. Options include:

  • Basic Auth (for development only, insecure in production)

  • Application Passwords (added in recent WordPress versions)

  • OAuth / JWT tokens for advanced setups
    Always use HTTPS to encrypt data in transit. Also sanitize and validate any data before display. Limit the data you expose. Use caching to prevent abuse or heavy load. If you fetch external APIs, check for errors, rate limits, and use caching so you don’t call the API on every visitor.

Performance and caching best-practices

Excessive or redundant API requests can slow your site or blow your server’s resources. To optimise:

  • Use set_transient() or wp_cache_set() to cache API responses for a defined period (e.g., 1 hour or 24 hours)

  • On API results, check HTTP status codes, handle errors gracefully

  • For front-end JS fetching, consider lazy loading or triggering only when needed (e.g., on scroll)

  • Limit the number of records you fetch via per_page or custom parameters

  • Use pagination when fetching large sets
    By caching responses you reduce external calls and improve user experience.

Common pitfalls and how to avoid them

  • Missing show_in_rest flag: Custom post types won’t appear via REST unless you set ‘show_in_rest’ => true when registering them.

  • Large payloads: Fetching huge JSON sets without filters causes slow load or browser memory issues. Use query parameters to constrain.

  • Not handling errors: External API may fail; your code must check for is_wp_error() or HTTP errors.

  • No caching: Making API calls on every page load degrades performance—always cache.

  • Unsecured endpoints: If you expose sensitive endpoints without permissions, you invite abuse—apply permission_callback or capabilities.

  • Ignoring rate limits: Third-party APIs may throttle you—monitor usage and fallback gracefully.

Typical use-cases of fetching data from API in WordPress

Here are examples of when you might implement this:

  • A news site fetching the latest headlines from a third-party feed and displaying a ticker

  • A travel blog showing up-to-date weather or flight status pulled from an external service

  • A WordPress-based mobile app that consumes WordPress as a headless CMS via REST endpoints

  • A plugin that fetches social media mentions or reviews and displays them in the dashboard

  • Exposing your WordPress content to external services via custom REST routes (e.g., mobile app, other website)

Step-by-step implementation scenario

Let’s walk through a small scenario: you want to fetch data from https://api.example.com/news and display the latest five items on a WordPress page.

  1. Create a function in functions.php: call wp_remote_get() to the external URL.

  2. Check response for errors.

  3. Parse json_decode( wp_remote_retrieve_body( $response ), true ).

  4. Cache the result with set_transient( ‘external_news_data’, $data, HOUR_IN_SECONDS ).

  5. Create a shortcode [external_news] that outputs an HTML list of titles and links. Inside shortcode callback you check the transient: if it is empty, fetch again, else use cached.

  6. Sanitize the output: escape titles, links.

  7. Optional: create a JS version: use fetch() when page loads, display results asynchronously in a div.

  8. Add error message in UI if external service is unavailable.

  9. Monitor performance & test with tools like Chrome DevTools and server logs.

Testing & troubleshooting

After implementation, you must test:

  • Does the fetch return the expected JSON and parse correctly?

  • Does the caching logic work (clear transient to force a new call)?

  • Is your shortcode output safe (no broken HTML, escaping done)?

  • On slow response from external API, does your site degrade gracefully?

  • If you created custom REST endpoints, test permissions and error responses (e.g., unauthorized access should return 403).

  • Use browser/network tools to check the API request and response size/time.

  • Monitor for potential vulnerabilities: are you exposing too much data?

Conclusion

Fetching data from APIs in WordPress opens powerful opportunities for dynamic content, integrations, and modern architectures. By combining WordPress’s built-in REST API with external endpoints, you unlock a flexible ecosystem. 

You must however plan for security, performance, caching, and proper error handling. With careful code, caching and testing you create robust integrations that delight your users and give you ever more dynamic WordPress sites.

Post a comment

Your email address will not be published.