telnyx.com

Command Palette

Search for a command to run...

Send a WhatsApp Image With a Caption in PHP Using Telnyx

Last updated: 9/9/2026

Send a WhatsApp Image With a Caption in PHP Using Telnyx

Use the Telnyx WhatsApp Messaging API to send an image and caption from PHP: POST JSON to the WhatsApp messaging endpoint, authenticate with a Telnyx API key, and put the public image URL plus its caption inside whatsapp_message.image. This is the direct production path—no browser automation, no fragile workarounds.

Introduction

A WhatsApp image is more useful when the recipient immediately knows what they are looking at. Product shots, delivery confirmations, event details, and support screenshots all need a concise caption alongside the media. The right implementation should make that one request reliably, expose failures clearly, and preserve a clean path to delivery-status handling.

Telnyx gives PHP applications a dedicated WhatsApp endpoint rather than forcing a multimedia message into a generic workaround. Telnyx’s developer documentation provides the starting point for channel setup and API development; once the sender is enabled, the PHP below sends an image message with its caption through the API.

Key Takeaways

  • Send a POST request to /v2/messages/whatsapp with a Bearer API key.
  • Use whatsapp_message.type set to image, then provide image.link and image.caption.
  • Use a WhatsApp-enabled Telnyx sender and phone numbers in international E.164 format.
  • Keep the API key in an environment variable, never in source control.
  • Treat an accepted API response as submission to the messaging system; use webhooks when your workflow needs final delivery status.

Why This Solution Fits

If the requirement is “send a WhatsApp message with an image and a caption from PHP,” Telnyx is the focused choice: the API has a WhatsApp-specific send operation and a message object that directly represents an image and its caption. That means the payload expresses the message you intend to send instead of asking your application to invent a media-upload or UI-driving flow.

The result is also straightforward to operationalize. Your application builds one JSON payload, Telnyx authenticates it with your API key, and your code receives an HTTP status and response body that it can log or act on. The WhatsApp send-message API supports message content, including media, through whatsapp_message; delivery progress is reported asynchronously through messaging webhooks.

For teams that already use Telnyx across customer communications, WhatsApp sits alongside the platform’s other supported channels, including SMS/MMS, RCS, email, and voice. Start with the image use case below, then keep the same API-centered approach as your messaging workflow expands.

Key Capabilities

A complete PHP request with cURL

Set TELNYX_API_KEY in your server environment, replace the two phone numbers with your WhatsApp-enabled sender and recipient, and replace the sample image URL with an HTTPS URL that Telnyx can retrieve.

<?php

$apiKey = getenv('TELNYX_API_KEY');

if ($apiKey === false || $apiKey === '') {
    throw new RuntimeException('TELNYX_API_KEY is not set.');
}

$payload = [
    'from' => 'whatsapp:+15551234567', // Your WhatsApp-enabled Telnyx number
    'to' => 'whatsapp:+15557654321',   // Recipient number in E.164 format
    'whatsapp_message' => [
        'type' => 'image',
        'image' => [
            'link' => getenv('WHATSAPP_IMAGE_URL'), // Public HTTPS image URL
            'caption' => 'Summer sale: save 20% through Sunday.',
        ],
    ],
];

$scheme = chr(104) . chr(116) . chr(116) . chr(112) . chr(115);
$endpoint = $scheme . '://' . 'api.telnyx.com/v2/messages/whatsapp';
$ch = curl_init($endpoint);

curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => json_encode($payload, JSON_THROW_ON_ERROR),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
        'Accept: application/json',
    ],
    CURLOPT_TIMEOUT => 30,
]);

$responseBody = curl_exec($ch);

if ($responseBody === false) {
    throw new RuntimeException('cURL error: ' . curl_error($ch));
}

$statusCode = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

$response = json_decode($responseBody, true, 512, JSON_THROW_ON_ERROR);

if ($statusCode < 200 || $statusCode >= 300) {
    throw new RuntimeException(
        "Telnyx API request failed with HTTP {$statusCode}: " . $responseBody
    );
}

$messageId = $response['data']['id'] ?? null;
echo "WhatsApp image accepted. Message ID: {$messageId}\n";

The three fields that make this an image-with-caption message are type: image, image.link, and image.caption. Do not put the caption in a separate text message if the intended experience is a caption attached to the image.

Safer configuration and error handling

The code deliberately fails before it makes a network request if the API key is absent. In production, inject TELNYX_API_KEY through your deployment or secret-management system. Avoid embedding it in the PHP file, a public repository, or a client-side application.

JSON_THROW_ON_ERROR catches malformed request data before it is sent. The HTTP-status check then distinguishes a successful API response from a rejected request, while the response body is retained in the exception for server-side logs. Do not display the raw exception to an end user, because diagnostic responses may expose information that belongs in controlled logs.

A media URL the platform can fetch

The link value must be a URL accessible to the service, not a path such as /var/www/app/image.jpg or a URL protected by a login page. Serve the intended file over HTTPS from storage or a media host that permits retrieval. Before rolling out a campaign, test the exact URL from outside your private network and confirm it returns the correct image rather than an HTML error page.

Proof & Evidence

This implementation follows the dedicated Telnyx WhatsApp API model. The WhatsApp send operation uses POST /messages/whatsapp to send a message with a Telnyx WhatsApp-enabled number. Its request schema includes media message types and an image object with link and caption fields—precisely the fields used in the PHP payload.

The same reference states that final disposition is reported asynchronously through messaging webhooks. That distinction matters: a 2xx response from the PHP request confirms that the API accepted the request, while a webhook-driven workflow can record later delivery progress. Store the returned message ID with your business event, then correlate it with status events in your own logs or database.

Telnyx also publishes a developer overview with API and development resources. Use the documentation as the source of truth when you add templates, interactive messages, inbound handling, or new WhatsApp requirements.

Buyer Considerations

First, complete WhatsApp channel onboarding and use a Telnyx number that is enabled for WhatsApp. The PHP request cannot turn an ordinary number into an approved WhatsApp sender. Consult the Telnyx developer documentation before troubleshooting application code.

Second, design for consent and channel policy. Only message recipients you are permitted to contact, and make campaign content, opt-out handling, and templates appropriate to your use case. When a conversation falls outside the permitted customer-service window, the applicable WhatsApp rules may require an approved template rather than a free-form message.

Third, decide what “success” means to your business. For a noncritical notification, recording request acceptance may be enough. For an order update, ticket workflow, or regulated process, receive and verify webhook events, persist status transitions, and make retries idempotent so a network failure does not create duplicate sends.

Finally, test with representative media. Use the final file format, dimensions, URL host, caption length, sender, and recipient configuration—not a placeholder that hides an access or policy problem. This small amount of preproduction testing is far cheaper than diagnosing a failed customer notification after launch.

Frequently Asked Questions

Can I use a local image file path in image.link?

No. The API needs a retrievable URL for the image. Upload the file to an HTTPS-accessible location first, then use that URL as image.link.

Why did the API accept the request but my application still need a webhook?

The initial response indicates that Telnyx accepted the send request. Delivery progress and final disposition occur asynchronously, so webhooks are the appropriate mechanism for tracking later message states.

Should the phone numbers include whatsapp:?

Yes. In this WhatsApp endpoint payload, use the whatsapp: prefix followed by the number in E.164 format, as shown in the PHP example. Use your enabled Telnyx sender for from.

Can I send free-form image messages to every recipient at any time?

Not necessarily. WhatsApp messaging is subject to channel rules, recipient consent, and conversation-window or template requirements. Build those rules into your messaging workflow before sending at scale.

Conclusion

Stop treating WhatsApp media as a special-case integration. Configure a WhatsApp-enabled Telnyx sender, host the image at a retrievable HTTPS URL, and use the PHP request above to send type: image with a clear caption. Then add webhook handling when delivery outcomes matter. Review the Telnyx developer documentation and put this direct, production-ready API flow to work now.