Home
/
Blog
/
How to Send iMessages from PHP (Laravel & WordPress)
March 29, 2026
8 min read
Nikita Jerschow

How to Send iMessages from PHP (Laravel & WordPress)

PHP developers can send iMessages using the Sendblue REST API with plain cURL, Laravel's HTTP client, or WordPress's wp_remote_post. This guide covers all three approaches with complete code examples for sending messages, receiving webhooks, and handling media.

Prerequisites

You need:

  • PHP 8.0+ with the cURL extension enabled (standard on most installs)
  • Sendblue API credentialssign up free to get your API key and secret
  • For Laravel: Laravel 10+ with the HTTP client (included by default)
  • For WordPress: WordPress 5.0+

The Sendblue API uses standard JSON over HTTPS, so no special PHP extensions are needed beyond cURL.

Plain PHP with cURL

Here's how to send an iMessage using PHP's built-in cURL functions:

<?php function sendImessage(string $number, string $content, ?string $mediaUrl = null): array { $payload = [ 'number' => $number, 'content' => $content, ]; if ($mediaUrl) { $payload['media_url'] = $mediaUrl; } $ch = curl_init('https://api.sendblue.co/api/send-message'); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'sb-api-key-id: ' . $_ENV['SENDBLUE_API_KEY'], 'sb-api-secret-key: ' . $_ENV['SENDBLUE_API_SECRET'], ], CURLOPT_POSTFIELDS => json_encode($payload), ]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); return json_decode($response, true); } // Send a message $result = sendImessage('+15551234567', 'Hello from PHP!'); print_r($result);

This works on any PHP installation with cURL enabled — shared hosting, VPS, Docker, or serverless.

Laravel Integration

Laravel's HTTP client makes API calls much cleaner. Create a service class:

<?php // app/Services/SendblueService.php namespace App\Services; use Illuminate\Support\Facades\Http; class SendblueService { private string $baseUrl = 'https://api.sendblue.co'; public function sendMessage( string $number, string $content, ?string $sendStyle = null, ?string $mediaUrl = null ): array { $payload = compact('number', 'content'); if ($sendStyle) $payload['send_style'] = $sendStyle; if ($mediaUrl) $payload['media_url'] = $mediaUrl; $response = Http::withHeaders([ 'sb-api-key-id' => config('services.sendblue.key'), 'sb-api-secret-key' => config('services.sendblue.secret'), ])->post("{$this->baseUrl}/api/send-message", $payload); return $response->json(); } public function evaluateService(string $number): array { $response = Http::withHeaders([ 'sb-api-key-id' => config('services.sendblue.key'), 'sb-api-secret-key' => config('services.sendblue.secret'), ])->get("{$this->baseUrl}/api/evaluate-service", [ 'number' => $number, ]); return $response->json(); } }

Add your credentials to config/services.php:

// config/services.php 'sendblue' => [ 'key' => env('SENDBLUE_API_KEY'), 'secret' => env('SENDBLUE_API_SECRET'), ],

Now use it anywhere in your Laravel app:

// In a controller or command: $sendblue = new SendblueService(); $sendblue->sendMessage( number: '+15551234567', content: 'Your appointment is confirmed for tomorrow at 2pm.', sendStyle: 'celebration' );

WordPress Integration

WordPress has its own HTTP helper that works without any additional plugins:

<?php function sb_send_imessage($number, $content, $media_url = null) { $body = [ 'number' => $number, 'content' => $content, ]; if ($media_url) { $body['media_url'] = $media_url; } $response = wp_remote_post('https://api.sendblue.co/api/send-message', [ 'headers' => [ 'Content-Type' => 'application/json', 'sb-api-key-id' => get_option('sendblue_api_key'), 'sb-api-secret-key' => get_option('sendblue_api_secret'), ], 'body' => wp_json_encode($body), ]); if (is_wp_error($response)) { error_log('Sendblue error: ' . $response->get_error_message()); return null; } return json_decode(wp_remote_retrieve_body($response), true); } // Example: Send message when a WooCommerce order is placed add_action('woocommerce_order_status_completed', function($order_id) { $order = wc_get_order($order_id); $phone = $order->get_billing_phone(); sb_send_imessage( $phone, "Your order #{$order_id} has shipped! Track it here: https://example.com/track/{$order_id}" ); });

Store your API credentials in WordPress options or wp-config.php constants for security.

Receive Webhooks in Laravel

Set up a webhook route and controller to handle incoming messages:

<?php // routes/api.php Route::post('/webhooks/sendblue/receive', [WebhookController::class, 'receive']); // app/Http/Controllers/WebhookController.php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Services\SendblueService; class WebhookController extends Controller { public function receive(Request $request) { $fromNumber = $request->input('from_number'); $content = $request->input('content'); $mediaUrl = $request->input('media_url'); $service = $request->input('service'); // iMessage, SMS, or RCS \Log::info("Received {$service} from {$fromNumber}: {$content}"); // Save to database \App\Models\Message::create([ 'from_number' => $fromNumber, 'content' => $content, 'media_url' => $mediaUrl, 'service' => $service, ]); // Auto-reply (new SendblueService())->sendMessage( number: $fromNumber, content: 'Thanks for your message! Our team will reply shortly.' ); return response()->json(['status' => 'ok']); } }

Make sure to exclude this route from CSRF protection in app/Http/Middleware/VerifyCsrfToken.php. Set your webhook URL in the Sendblue dashboard.

Send Media and Contact Cards

Attach images, PDFs, videos, or vCards to any message:

// Send an image $sendblue->sendMessage( number: '+15551234567', content: 'Here is your receipt:', mediaUrl: 'https://example.com/receipt.pdf' ); // Send a contact card (vCard) $sendblue->sendMessage( number: '+15551234567', mediaUrl: 'https://example.com/agent.vcf' );

Contact cards are a powerful feature unique to Sendblue. When a recipient saves the vCard, your business name appears on all future messages. This is especially effective for sales outreach and customer support.

Error Handling

Always handle API errors gracefully. Here's a robust pattern for Laravel:

public function sendMessage(string $number, string $content): array { try { $response = Http::withHeaders([ 'sb-api-key-id' => config('services.sendblue.key'), 'sb-api-secret-key' => config('services.sendblue.secret'), ]) ->timeout(30) ->retry(3, 1000) ->post('https://api.sendblue.co/api/send-message', [ 'number' => $number, 'content' => $content, ]); if ($response->failed()) { \Log::error('Sendblue API error', [ 'status' => $response->status(), 'body' => $response->json(), ]); } return $response->json(); } catch (\Exception $e) { \Log::error('Sendblue exception: ' . $e->getMessage()); return ['error' => $e->getMessage()]; } }

Laravel's HTTP client supports built-in retries and timeouts, which is ideal for reliable message delivery.

Next Steps

You're now sending iMessages from PHP. Explore further:

Get your free API keys and start sending iMessages from PHP today.

Ready to send your first iMessage?

Get API access in minutes. Free sandbox, no credit card required.

Get API Access