Skip to main content

Proxy API (deprecated)

Deprecated since version 2.3.0

The Proxy API will be removed in an upcoming release. It existed to expose the API through your WordPress site, back when there was no public API to call directly. There is now: the Joinotify API does the same without depending on your site being up, with more message types, scheduling and real delivery confirmation.

The routes still work for now. If you are still using them, see how to migrate below.

The Proxy API exposes REST endpoints on your own site that forward the send to Joinotify. An external system calls your domain; the plugin resolves the transport, the authentication and the queue.

It is useful for:

  • Security — your Joinotify token never leaves your server; callers use a key of their own that you can rotate at any time.
  • Simplicity — two endpoints with a minimal body, no need to learn the full API contract.
  • Control — WordPress sits in the middle, so you can throttle, filter or log requests before forwarding them.
When to call the Joinotify API directly

If the sending system already speaks HTTP with bearer authentication, calling the Joinotify API directly is simpler and does not depend on your site being up. The Proxy API exists for the cases where WordPress has to sit in the middle.

How to migrate​

The destination is the Joinotify API, called directly by the system that sends. The key is the same one the plugin already holds — take it from Joinotify → Settings → Integrations, on the WhatsApp card, or issue your own in the dashboard.

BeforeNow
POST https://yoursite.com/wp-json/joinotify/v1/send-message/textPOST https://api.joinotify.com/messages with {"type":"text"}
POST .../send-message/mediaPOST https://api.joinotify.com/v1/{phone_number_id}/messages
X-API-Key headerAuthorization: Bearer sk_live_… header
receiver / messageto / body
The same send, without WordPress in the middle
curl -X POST https://api.joinotify.com/messages \
-H 'Authorization: Bearer sk_live_xxx' \
-H 'Content-Type: application/json' \
-d '{ "type": "text", "to": "5511910203040", "body": "Hello!" }'

What you gain: the message types the Proxy API never exposed (template, buttons, list, carousel, media by id), scheduling with cancellation and real delivery status — the Proxy API only ever said the message was accepted.

What you lose: WordPress stops sitting in the middle, so any filtering or logging you hung there has to move.

Telling whether anyone still uses it​

Every proxy response carries two headers:

Deprecation: true
X-Joinotify-Deprecation: The Joinotify Proxy API is deprecated and will be removed in an
upcoming release. Migrate to the Joinotify API (official WhatsApp Cloud API).

And every call is written to the debug log as a WARNING. That is how you find which integration still points at the old shape before the routes go away.

Enabling it​

Under Joinotify → Settings → General, in the Proxy API card:

FieldDefaultWhat it does
Enable Proxy APIoffRegisters the endpoints on the site
Text routesend-message/textPath of the text message route
Media routesend-message/mediaPath of the media message route
API keyemptyValue expected in the X-API-Key header

The routes live under the joinotify/v1 namespace. With the default values, the final addresses are:

https://yoursite.com/wp-json/joinotify/v1/send-message/text
https://yoursite.com/wp-json/joinotify/v1/send-message/media
They ship disabled

The routes are only registered with the Proxy API enabled — and since 2.4.0 it ships disabled on new installs. Without enabling it, WordPress answers 404.

Authentication​

Send the configured key in the X-API-Key header. Without it — or with a different value — the response is 403.

Sending a text message​

POST /wp-json/joinotify/v1/send-message/text
curl -X POST https://yoursite.com/wp-json/joinotify/v1/send-message/text \
-H 'X-API-Key: cb9sDT9MRjlMnBIQglneN6uEEKxvrcpW' \
-H 'Content-Type: application/json' \
-d '{
"sender": "5541912345678",
"receiver": "5511910203040",
"message": "Your order #1042 is confirmed.",
"delay": 60
}'
FieldRequiredDescription
senderyesSender phone in international format
receiveryesRecipient phone in international format
messageyesThe message text
delaynoWait in seconds before sending. Without it, the send is immediate

Sending a media message​

POST /wp-json/joinotify/v1/send-message/media
curl -X POST https://yoursite.com/wp-json/joinotify/v1/send-message/media \
-H 'X-API-Key: cb9sDT9MRjlMnBIQglneN6uEEKxvrcpW' \
-H 'Content-Type: application/json' \
-d '{
"sender": "5541912345678",
"receiver": "5511910203040",
"media_type": "document",
"media_url": "https://yoursite.com/wp-content/uploads/2026/07/manual.pdf",
"caption": "Here is the product manual."
}'
FieldRequiredDescription
senderyesSender phone in international format
receiveryesRecipient phone in international format
media_typeyesimage, video, document or audio
media_urlyesFile URL, on your site or external
captionnoMedia caption
delaynoWait in seconds before sending

Accepted formats per type​

.jpeg · .png · .gif · .bmp · .webp

To allow other formats, use the Joinotify/Validations/Get_Mime_Types filter — see Developer resources.

Example: announce a published post​

The snippet below goes in the theme's functions.php or in a snippets plugin such as WPCode. It calls the site's own Proxy API, reusing the helpers that resolve the address and the key.

functions.php
add_action( 'publish_post', 'meumouse_announce_published_post' );

/**
* Sends a text message through the Proxy API when a post is published.
*
* @param int $post_id | ID of the published post.
*/
function meumouse_announce_published_post( $post_id ) {
if ( get_post_type( $post_id ) !== 'post' ) {
return;
}

$post = get_post( $post_id );

$message = sprintf(
"Hey, a new post just went live!\n\nTitle: %s\nAuthor: %s\nLink: %s",
$post->post_title,
get_the_author_meta( 'display_name', $post->post_author ),
get_permalink( $post_id )
);

$response = wp_remote_post( joinotify_proxy_api_text_message_text_endpoint(), array(
'headers' => array(
'Content-Type' => 'application/json',
'X-API-Key' => joinotify_get_proxy_api_key(),
),
'body' => wp_json_encode( array(
'sender' => joinotify_get_first_sender(),
'receiver' => '5511910203040',
'message' => $message,
) ),
'timeout' => 15,
) );

if ( is_wp_error( $response ) ) {
error_log( 'Failed to send the text message: ' . $response->get_error_message() );
}
}
Calling from inside the site itself

When the code already runs on WordPress, you can skip the HTTP round trip and call joinotify_send_whatsapp_message_text() directly. The Proxy API is for callers outside the site.

The 24-hour window applies here too​

With the Cloud API transport, a free-form text message is only delivered inside the 24-hour window. Outside it, an approved template is required — and the Proxy API does not expose template sending. See Delivering through Joinotify Cloud.