# MMS Send with PHP and Laravel ## What Does This Example Do? Build a production-ready Laravel endpoint that sends MMS messages with media attachments using the Telnyx PHP SDK. This tutorial demonstrates the new client-based initialization pattern, proper error handling for telecom APIs, secure credential management via environment variables, and Laravel's idiomatic patterns for request validation and response serialization. ## Who Is This For? - **PHP developers** building sms features with Laravel. - **Backend engineers** integrating telephony or messaging into existing applications. - **DevOps teams** looking for containerized, production-ready telecom examples. - **Startups and enterprises** replacing legacy telecom providers with a modern API-first platform. ## Why Telnyx? Telnyx is an **AI Communications Infrastructure** platform that gives developers a single API for [voice](https://telnyx.com/products/voice-ai-agents), [messaging](https://telnyx.com/products/sms-api), [SIP](https://telnyx.com/products/sip-trunks), [AI](https://telnyx.com/ai-assistants), and [IoT](https://telnyx.com/products/iot-sim-card) — no Frankenstack required. - **Integrated platform** — [Voice](https://telnyx.com/products/voice-ai-agents), [SMS](https://telnyx.com/products/sms-api), [SIP trunking](https://telnyx.com/products/sip-trunks), [AI assistants](https://telnyx.com/ai-assistants), and [IoT SIM management](https://telnyx.com/products/iot-sim-card) under one roof. No stitching together multiple vendors. - **Global private network** — Calls and messages traverse the Telnyx-owned IP network for lower latency and higher reliability than the public internet. - **Developer-first** — SDKs for Python, Node.js, Go, Ruby, Java, and PHP. Comprehensive webhook event model. Sandbox environment for testing. - **Competitive pricing** — Pay-as-you-go with no minimums, contracts, or per-seat fees. ## Prerequisites - PHP 8.1 or higher. - Laravel 10 or higher. - Composer (PHP package manager). - A Telnyx account with an active API key from the [Telnyx Portal](https://portal.telnyx.com). - A Telnyx phone number enabled for outbound MMS. - A publicly accessible URL or ngrok tunnel for testing (optional, for webhook testing). ## Quick Start ### Option 1: Local (recommended) ```bash git clone https://github.com/team-telnyx/telnyx-code-examples.git cd telnyx-code-examples/send-mms-picture-message-php cp .env.example .env # Edit .env with your Telnyx API key and phone number make setup make run ``` ### Option 3: Manual See the [Implementation Details](#implementation-details) section below for step-by-step instructions. ## Implementation Details Create a service class to encapsulate MMS sending logic. Generate a new service: ```bash php artisan make:service TelnyxMmsService ``` Edit `app/Services/TelnyxMmsService.php`: ```php client = new Client(apiKey: config('services.telnyx.api_key')); $this->fromNumber = config('services.telnyx.phone_number'); if (!$this->fromNumber) { throw new \RuntimeException('TELNYX_PHONE_NUMBER environment variable not set'); } } /** * Send MMS message with media attachments. * * @param string $toNumber Recipient phone number in E.164 format. * @param string $message Message text content. * @param array $mediaUrls Array of publicly accessible media URLs (images, videos, etc.). * @return array JSON-serializable response data. * @throws \InvalidArgumentException If phone number format is invalid. * @throws ApiException If Telnyx API call fails. */ public function sendMms(string $toNumber, string $message, array $mediaUrls): array { // Validate E.164 format to prevent API errors if (!str_starts_with($toNumber, '+')) { throw new \InvalidArgumentException( 'Phone number must be in E.164 format (e.g., +15551234567)' ); } if (empty($mediaUrls)) { throw new \InvalidArgumentException( 'At least one media URL is required for MMS' ); } // Validate media URLs are accessible foreach ($mediaUrls as $url) { if (!filter_var($url, FILTER_VALIDATE_URL)) { throw new \InvalidArgumentException( "Invalid media URL: {$url}" ); } } // Create MMS message via Telnyx API $response = $this->client->messages->send([ 'from_' => $this->fromNumber, 'to' => $toNumber, 'text' => $message, 'media_urls' => $mediaUrls, ]); // Extract serializable data — SDK objects are NOT JSON-serializable return [ 'message_id' => $response->data->id, 'status' => $response->data->to[0]->status ?? 'pending', 'from' => $this->fromNumber, 'to' => $toNumber, 'media_count' => count($mediaUrls), ]; } } ``` Create a controller to handle HTTP requests. Generate a new controller: ```bash php artisan make:controller MmsController ``` Edit `app/Http/Controllers/MmsController.php`: ```php validate([ 'to' => 'required|string|regex:/^\+\d{1,15}$/', 'message' => 'required|string|max:1000', 'media_urls' => 'required|array|min:1', 'media_urls.*' => 'required|url', ]); try { $result = $this->mmsService->sendMms( $validated['to'], $validated['message'], $validated['media_urls'] ); return response()->json($result, 200); } catch (AuthenticationException) { return response()->json(['error' => 'Invalid API key'], 401); } catch (RateLimitException) { return response()->json( ['error' => 'Rate limit exceeded. Please slow down.'], 429 ); } catch (ApiException $e) { return response()->json( [ 'error' => $e->getMessage(), 'status_code' => $e->getHttpStatus(), ], $e->getHttpStatus() ?? 500 ); } catch (\InvalidArgumentException $e) { return response()->json(['error' => $e->getMessage()], 400); } catch (\Exception $e) { return response()->json( ['error' => 'Network error connecting to Telnyx'], 503 ); } } } ``` Register the route in `routes/api.php`: ```php Search & Buy, and purchase a number with the capabilities you need (SMS, voice, or both). ## Resources - [Messaging Overview](https://developers.telnyx.com/docs/messaging) - [Send an SMS — Quickstart](https://developers.telnyx.com/docs/messaging/messages/send-message) - [Messaging API Reference](https://developers.telnyx.com/api-reference/messages/send-a-message) - [Telnyx SMS API](https://telnyx.com/products/sms-api) - [Messaging Pricing](https://telnyx.com/pricing/messaging) ## Related Examples - [Send Bulk SMS Messages](https://raw.githubusercontent.com/team-telnyx/telnyx-code-examples/main//tutorials/sms/php/send-bulk-sms). - [Receive SMS Webhooks with Laravel](https://raw.githubusercontent.com/team-telnyx/telnyx-code-examples/main//tutorials/sms/php/receive-sms-webhook). - [Implement Two-Factor Authentication with SMS](https://raw.githubusercontent.com/team-telnyx/telnyx-code-examples/main//tutorials/sms/php/otp-2fa).