How to Monitor API Requests in WordPress Plugins

How to Monitor API Requests in WordPress Plugins

If your WordPress plugin makes HTTP calls, I’d track four things right away: where requests go, how long they take, whether they fail, and what triggered them. That alone helps me spot timeouts, blocked domains, bad responses, and slow third-party services before they turn into user-facing problems.

Here’s the short version:

  • I use WordPress HTTP hooks and essential plugins to watch outbound calls
  • I treat outgoing HTTP and incoming REST traffic as two different paths
  • I log URL, method, status code, runtime, source, and cleaned error details
  • I mask secrets like tokens, API keys, passwords, cookies, and nonces before saving anything
  • I use Query Monitor for live checks and REST logging tools for route history
  • I store logs in a custom table or external log service if I need search, filters, and retention
  • I prune old logs, skip noisy hosts, and watch for repeat failures like cURL error 28 timeouts

A few numbers matter here. WordPress often uses a 5-second timeout for HTTP requests. That means even 3 stalled calls can add up to 15 seconds of delay in a bad flow. And if I keep raw bodies for every request, log size can grow fast, so I cut large payloads to about 2 KB and delete old rows after 30 days.

The main idea is simple: monitor less, but monitor the right things. I want enough detail to fix errors fast without filling my database, slowing my site, or storing secret data by mistake.

From there, the article walks through the setup: hooks first, tools second, then structured logs and alerts.

Debugging WordPress with Query Monitor Plugin

WordPress

Step 1: Set up basic monitoring with WordPress HTTP API hooks

Start with the built-in WordPress HTTP API hooks. They let you see outbound requests without changing every plugin or theme that makes them. A simple setup works well here: use pre_http_request to inspect or stop calls before they leave the site, and use http_api_debug to record what came back. If you later want to review trends over time, move that data into a custom table.

Log outgoing requests with http_api_debug

http_api_debug gives you the response or WP_Error result, the request arguments, the transport used, and the target URL [5][6]. That’s enough to build a useful request log.

If you also want response time, record microtime(true) in pre_http_request and subtract it inside http_api_debug.

// In your mu-plugin file add_filter( 'pre_http_request', function( $preempt, $args, $url ) {     // Use a unique key to avoid overwriting concurrent calls to the same URL     $request_key = $url . '_' . uniqid( '', true );     $GLOBALS['api_monitor_start'][ $request_key ] = microtime( true );     $GLOBALS['api_monitor_keys'][ $url ] = $request_key;     return $preempt; }, 10, 3 );  add_action( 'http_api_debug', function( $response, $context, $transport, $args, $url ) {     $request_key = $GLOBALS['api_monitor_keys'][ $url ] ?? null;     $start       = $request_key ? ( $GLOBALS['api_monitor_start'][ $request_key ] ?? microtime( true ) ) : microtime( true );     $runtime     = round( microtime( true ) - $start, 3 );     $method      = strtoupper( $args['method'] ?? 'GET' );      if ( is_wp_error( $response ) ) {         $status_code   = null;         $error_message = $response->get_error_message();     } else {         $status_code   = wp_remote_retrieve_response_code( $response );         $error_message = null;     }      api_monitor_write_log( $url, $method, $status_code, $error_message, $runtime, $args, $response ); }, 10, 5 ); 

One small thing matters a lot: always check is_wp_error( $response ) before reading the status code. That’s how you catch failed requests like timeouts or DNS errors instead of treating them like normal HTTP responses [2][6].

And if you save request arguments or response data, clean out secrets first. Redact fields like authorization, x-api-key, access_token, nonce, and password before anything hits your logs [1].

Inspect or block risky calls with pre_http_request

You can use that same hook path to stop calls you don’t expect. Since pre_http_request is a filter, returning anything other than false prevents the request from being sent. That makes it a solid place to check the target URL against an allowlist [1].

add_filter( 'pre_http_request', function( $preempt, $args, $url ) {     $allowed_domains = [ 'api.stripe.com', 'api.mailgun.net', 'www.googleapis.com' ];     $host = parse_url( $url, PHP_URL_HOST );      if ( ! in_array( $host, $allowed_domains, true ) ) {         error_log( '[API Monitor] Blocked unexpected domain: ' . $host );         return new WP_Error( 'blocked_domain', 'Request blocked by API monitor allowlist.' );     }      return $preempt; }, 10, 3 ); 

This is a clean way to catch odd traffic early. If some plugin tries to call an unknown host, the request never leaves your server [1].

Store logs in a custom table

File logging is fine at first, but a custom table makes slow and failed requests much easier to sort, filter, and review. Use $wpdb and dbDelta on plugin activation so WordPress can create or update the schema safely [1].

function api_monitor_create_table() {     global $wpdb;     $table   = $wpdb->prefix . 'api_monitor_log';     $charset = $wpdb->get_charset_collate();      $sql = "CREATE TABLE $table (         id             BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,         url            TEXT NOT NULL,         method         VARCHAR(10) NOT NULL,         request_status VARCHAR(20) NOT NULL,         runtime        DECIMAL(10,3) NOT NULL DEFAULT 0.000,         request_args   MEDIUMTEXT DEFAULT NULL,         response       MEDIUMTEXT DEFAULT NULL,         date_added     DOUBLE NOT NULL,         PRIMARY KEY (id),         KEY runtime (runtime),         KEY date_added (date_added)     ) $charset;";      require_once ABSPATH . 'wp-admin/includes/upgrade.php';     dbDelta( $sql ); } 

A few details make this setup easier to work with:

  • Store the timestamp in UTC when writing each row, then convert it for display in the admin UI [1].
  • Add indexes for runtime and date_added so searches for slow requests stay efficient, such as SELECT * FROM wp_api_monitor_log WHERE runtime > 2.0 [1].
  • Use WP-Cron to delete logs older than 30 days.

That gives you a simple monitoring base: inspect requests before send, log what comes back, and keep the data in a format you can query later.

Step 2: Inspect API traffic with developer tools and logging plugins

WordPress API Monitoring: Tools & Storage Options Compared

WordPress API Monitoring: Tools & Storage Options Compared

Developer tools and logging plugins help you see what your hooks pick up and what slips past them. During development, use them to check request behavior before you set up long-term logs.

Use Query Monitor to find slow or failing HTTP requests

Query Monitor includes a dedicated HTTP API Requests panel that tracks WordPress HTTP API calls. For each request, it records the URL, HTTP method, response code, time taken, and the Component behind the call [7][3].

It also shows a call stack for each request, which makes it much easier to trace the exact function behind an odd or repeated API call [7][3]. In April 2026, Query Monitor 4.0 added a timeline view that shows when HTTP requests fire during the page lifecycle, alongside database queries and other events [7].

For most day-to-day debugging in development, Query Monitor does the job well. But if you’re checking incoming endpoint traffic, you’ll want a logging tool that keeps the full request and response body.

Use REST API logging tools for incoming route activity

WP REST API Log (wp-rest-api-log) records the HTTP method, response status, source, and full request/response body for every call that hits your endpoints [4]. Use it when you need a persistent, searchable history of incoming traffic [4].

Compare tools by traffic type and captured data

Use the table below to match each tool to the traffic you need to inspect.

Tool Traffic Type Best For Key Data Captured
Query Monitor Outgoing HTTP + Incoming REST Live debugging during development URL, component, time, call stack, status code [7][3]
WP REST API Log Incoming REST Auditing & webhook history Method, status, source, full request/response body [4]

After debugging, you can turn what you found into structured logs and alerts.

Step 3: Add structured logging and alerts in your plugin

Once you’ve used developer tools to see how your API traffic behaves, the next move is to bake repeatable logging into your plugin.

Log request and response data in a structured format

After you’ve debugged the request flow, keep that same data in logs you can search later. Hook-based monitoring helps you see a request in the moment. Structured logs let you search that history over time.

Use structured JSON logs instead of manual error_log() calls. JSON is machine-readable, which means log tools can index and query it automatically [8].

Each log entry should include the same core fields every time:

  • timestamp (ISO 8601 format)
  • request_id (to link related events)
  • endpoint
  • method
  • status_code
  • duration_ms
  • user_id
  • error_message if the call fails [8][1]

It also helps to add a request_source field so you know where the call came from, like a cron job, an AJAX handler, or a REST route. That small detail can save a lot of time when you’re tracking down a problem later [1].

Before you store anything, redact sensitive data. Following WordPress development best practices for secure sites, that includes tokens, keys, cookies, passwords, and nonces [1]. You should also truncate large request and response bodies to about 2 KB so your logs don’t balloon in size [1].

Choose between file, database, and external monitoring storage

Once your log format is set, the next choice is where to store those records. The right option depends on traffic, how often you need to search logs, and how long you plan to keep them.

Storage Type Overhead Searchability Best for production Maintenance
File-based (debug.log) Low (if rotated) Poor (requires grep or tail) Low (risk of disk fill) High (manual cleanup)
Database (Custom Table) Moderate High (via SQL/WP Admin) Medium (can impact DB performance) Medium (requires pruning cron)
External (APM/Log SaaS) Minimal (offloaded) Excellent (dashboards/filters) High (best for scale) Low (managed by provider)

For high-traffic sites, sending logs to an external service usually works better than trying to manage local storage and cleanup on your own.

Best practices: keep monitoring useful, safe, and lightweight

Cut performance overhead and control log growth

Once logging is set up, the job changes. Now you need to keep it lean.

The main problem is simple: too much logging. One plugin action can fire off dozens of outbound requests. If you log every single one, storage fills up fast.

A better move is selective logging. Skip high-volume, low-risk hosts like api.wordpress.org and secure.gravatar.com. For low-priority calls, such as analytics pings and tracking pixels, use short 2–3 second timeouts. WordPress uses a 5-second timeout by default, so three stalled requests can stack up to 15 seconds of latency for a real visitor [9].

Keep retention short, and prune logs on a set schedule.

After you cut log volume, stop staring at raw traffic counts. Look for failure patterns instead. That’s usually where the useful signal lives.

Review security signals and retest after updates

Once logging is running, treat it like an early warning system, not just a debugging aid. Watch for repeated 4xx/5xx responses, SSL errors, and connection refused messages. Those signs often point to a misconfigured integration or an API provider outage [2].

Any time you update WordPress core, a plugin, or your hosting setup, retest your hooks and spot-check your logs.

Used this way, monitoring stays helpful without turning into another source of overhead.

Key takeaways

Keep monitoring selective, redacted, and short-lived. Log only what helps you diagnose failures, then prune the rest.

FAQs

How do I track API request time in WordPress?

To track API request time in WordPress, use diagnostic tools that log execution time and response duration.

  • Inspect HTTP Requests records runtime for outgoing HTTP calls.
  • HTTP Requests Manager shows timing metrics and backtraces.
  • Query Monitor displays HTTP API and REST API request durations in the admin toolbar.
  • WP Debug Toolkit CLI profiles REST API endpoints with an execution-time breakdown.

What should I redact before logging API requests?

Always redact sensitive information before logging API requests in your WordPress plugin. That means authentication tokens, API keys, user passwords, and personally identifiable information (PII).

Before you write request or response payloads to logs or database tables, sanitize them first. Keep the parts that help with debugging – like the endpoint URL, timestamp, and response code – but mask anything confidential.

When should I use a custom table for API logs?

Use a custom database table for API logs when you need structured data that’s easy to filter, search, and manage in the WordPress admin dashboard.

This setup works best when you’re dealing with a lot of log entries, more complex queries, or a familiar admin view built with WP_List_Table. It gives you a clean way to sort through data without digging through messy files.

That said, custom tables can put more load on the database. So in some cases, developers split the job: files store raw logs, while the database keeps only the errors that need action.

Related Blog Posts


Discover more from WP Winners 🏆

Subscribe to get the latest posts sent to your email.

More WorDPRESS Tips, tutorials and Guides

Discover more from WP Winners 🏆

Subscribe now to keep reading and get access to the full archive.

Continue reading