backlinkindexersoftware.comSoftware and API handbook

Submitting WordPress posts on publish

Published

WordPress can submit each new post for crawling the moment it goes live. A small plugin hooks the transition_post_status action, ignores everything except a change into the publish status, and posts the permalink to the IndexChex single-URL endpoint, POST /v2/google/url, with the API key read from wp-config.php.

The idea

New posts are the URLs most worth getting crawled quickly, and WordPress already knows exactly when each one goes live. Instead of exporting URLs to another tool, a few lines of PHP can send each permalink to an indexing API at publish time. This recipe uses the single-URL endpoint of IndexChex, the publisher of this handbook; the IndexChex software and API page summarises the service and its credit costs.

WordPress sites usually also expose an XML sitemap, and some hosts or plugins support IndexNow. A crawl submission is a separate step that asks for a Googlebot visit; it does not replace a sitemap, and it does not make Google index a page it would otherwise skip.

Choosing the hook

The WordPress developer reference documents transition_post_status as firing "when a post is transitioned from one status to another", with three arguments: the new status, the old status and the WP_Post object. Contributed notes on the same page point out that it also fires when a published post is merely updated, with old and new status both publish. The plugin therefore needs two checks: the new status must be publish, and the old one must not be.

The plugin

Save this as wp-content/plugins/indexchex-submit/indexchex-submit.php and activate it under Plugins.

<?php
/**
 * Plugin Name: IndexChex submit on publish
 * Description: Sends newly published post URLs to the IndexChex single-URL endpoint.
 */

defined( 'ABSPATH' ) || exit;

add_action( 'transition_post_status', 'ixc_submit_on_publish', 10, 3 );

function ixc_submit_on_publish( $new_status, $old_status, $post ) {
	if ( 'publish' !== $new_status || 'publish' === $old_status ) {
		return;
	}
	if ( 'post' !== $post->post_type || ! defined( 'INDEXCHEX_API_KEY' ) ) {
		return;
	}

	$response = wp_remote_post(
		'https://indexchex.com/api/v2/google/url',
		array(
			'headers' => array(
				'Authorization' => INDEXCHEX_API_KEY,
				'Content-Type'  => 'application/json',
				'Accept'        => 'application/json',
			),
			'body'    => wp_json_encode( array( 'url' => get_permalink( $post ) ) ),
			'timeout' => 15,
		)
	);

	if ( is_wp_error( $response ) ) {
		error_log( 'IndexChex submit failed: ' . $response->get_error_message() );
		return;
	}

	$body = json_decode( wp_remote_retrieve_body( $response ), true );
	if ( ! isset( $body['code'] ) || 0 !== $body['code'] ) {
		error_log( 'IndexChex submit rejected: ' . wp_remote_retrieve_body( $response ) );
	}
}

Add the key to wp-config.php, above the "stop editing" line, so it never sits in the database or in the plugin file:

define( 'INDEXCHEX_API_KEY', 'paste-your-key-here' );

What the endpoint returns

HTTP statusBodyMeaning
200{"code": 0}Accepted as a standard submission
402{"code": 1, "message": ...}Not enough credits
422{"code": 3, "message": ...}Invalid request, for example a malformed URL
429{"code": 2, "message": ...}Too many requests in the current minute
500{"code": 2}The request could not be processed; try later

The response shape follows SpeedyIndex's v2 schema, so an existing SpeedyIndex WordPress snippet usually needs only a new base URL and key; see migrating a SpeedyIndex integration. Each accepted post is a standard submission at 1 credit. Error handling beyond logging is covered in handling indexing API errors.

Adjusting the filter

  • Pages and custom post types. Replace the 'post' !== check with ! in_array( $post->post_type, array( 'post', 'page', 'product' ), true ).
  • Skip noindexed posts. If an SEO plugin marks a post noindex, submitting it wastes a credit, because Google will drop the page when it sees the rule. Read that plugin's post meta and return early.
  • Private and password-protected posts. private is a separate status and never triggers the hook, but password-protected posts are published; check post_password if those should be skipped.
  • Staging sites. Leave INDEXCHEX_API_KEY undefined on staging; the function returns before making any request.

Checking the result later

The single-URL endpoint does not schedule a re-check. To confirm the posts were indexed, collect a week's permalinks and run them through an index check, either with the Python script or a Google Sheets workflow. Sites without access to plugin code can achieve a similar flow from an RSS trigger with Zapier or Make.

Where this fits

A publish hook is the lightest form of automation: it covers one site, one event and one call. Agencies managing many sites often prefer a central script or a dedicated tool; what backlink indexer software is describes that range, and backlink indexer APIs compares the request formats different providers use. Field-level documentation is in the API reference.

FAQ

Why not hook save_post or publish_post?

save_post fires on every save, including autosaves and edits. transition_post_status passes both the old and new status, so the plugin can act only when a post moves into publish from another status.

Will scheduled posts be submitted?

Yes. When WordPress publishes a scheduled post, its status changes from future to publish, which fires the same hook at the scheduled time.

Does updating a published post submit it again?

No. An update leaves the status at publish, and the plugin returns early when the old status is already publish.

Does the request slow down publishing?

The call runs during the save request and waits up to the 15-second timeout set in the code. Lower the timeout, or move the call to a scheduled event, if editors notice a delay.

Terms used on this page

Sources

  1. WordPress Developer Resources: transition_post_status
  2. IndexChex public API reference

Cite this entry

IndexChex. (2026, October 8). Submitting WordPress posts on publish. backlinkindexersoftware.com. https://backlinkindexersoftware.com/wordpress-publish-hook/