> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.pinnacle.sh/v-2/api-reference/messages/send-mms/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.pinnacle.sh/_mcp/server. # Send MMS Message POST https://api.pinnacle.sh/messages/send/mms Content-Type: application/json Send a MMS immediately or schedule it for future delivery. Reference: https://docs.pinnacle.sh/api-reference/messages/send-mms ## Authentication - `PINNACLE-API-KEY` header (required) — API Key authentication via header ## Request ### Body (application/json) This endpoint expects a SendMmsSchema. - `from` (string, required) — Phone number you want to send the message from in E.164 format. - `mediaUrls` (list of string, required) — Media file URLs to send. See [supported media types](https://app.pinnacle.sh/supported-file-types?type=MMS). - `text` (string, required) — Message text to accompany the media. - `to` (string, required) — Recipient's phone number in E.164 format. - `options` (SendMmsOptions, optional) — Control how your MMS is processed and delivered. ## Response ### 200 Successfully sent or scheduled the message. Each message part can be tracked independently using its unique message ID. Use our [/messages/:id](./get) endpoint to track your messages. - `messages_mms_send_Response_200` ## Errors ### 400 Bad Request Error The request was unacceptable, often due to providing an invalid update. Errors may originate from invalid payload or from Pinnacle's additional validation checks. For example, providing an URL that cannot be accessed, updating a campaign that is currently being reviewed, updating data that you cannot access, sending a malformed message, and so on. For `Pinnacle Validation Error` inspect the `error` payload to determine the source of the failure. These errors are likely due to additional validation and business logic checks. For `Request Validation Error` inspect the `description` and `errors` payload to determine the source of failure. These errors are likely due to invalid payload inside the request. - `SendMmsMessageRequestBadRequestError` ### 401 Unauthorized Error The request lacks valid authentication credentials or the provided credentials are invalid. Ensure you're including a valid API key in the request headers and that your account has the necessary permissions to access this endpoint. - `error` (string, required) — Human-readable description of the error that occurred, corresponding to the HTTP status code. ### 402 Payment Required Error Insufficient credits to complete this request. This occurs when your account balance is below the required amount for processing the operation. Please add credits to your account to continue using the service. - `error` (string, required) — Human-readable description of the error that occurred, corresponding to the HTTP status code. ### 403 Forbidden Error Your subscription does not include access to this feature. This occurs when attempting to use functionality that requires a higher subscription tier. Please upgrade your subscription to access this feature. - `error` (string, required) — Human-readable description of the error that occurred, corresponding to the HTTP status code. ### 404 Not Found Error The requested resource could not be found. This may occur if the identifier is incorrect, the resource has been deleted, or you don't have permission to access it. - `error` (string, required) — Human-readable description of the error that occurred, corresponding to the HTTP status code. ### 500 Internal Server Error An unexpected error occurred on Pinnacle's servers while processing your request. If this error persists, please contact support with the request details. - `error` (string, required) — Human-readable description of the error that occurred, corresponding to the HTTP status code. ### 501 Not Implemented Error The requested functionality is not implemented on the server. This typically indicates that the feature or endpoint you attempted to access is unavailable or not yet supported. - `error` (string, required) — Human-readable description of the error that occurred, corresponding to the HTTP status code. ## Types ### SendMmsOptions Control how your MMS is processed and delivered. - `multiple_messages` (boolean, required, default: false) — Allow splitting large content into multiple MMS messages if size limits are exceeded. If `false`, MMS over the limit will throw an error and won't be sent. - `validate` (boolean, required, default: false) — Set to true to check this message and throw an error when validation fails. If errors occur, the message is not sent. Otherwise message is sent after validation. - `schedule` (ScheduleSchema, optional) — Define when and how your message should be sent. - `tracking` (enum, optional) — Enable tracking on sent messages. If not provided, messages are not tracked. You will not be able to react to these messages unless you provide the [options.force](./react#request.body.options.force) field. `ID` - Append an explicit ID at the end of the message for tracking. Users will see this ID. `HIDDEN` - Invisible IDs are sent with messages for tracking. Will not be visible to users but will lead to slightly longer message lengths. - Allowed values: `ID`, `HIDDEN` ### SendMmsResponse - `messageIds` (list of string, required) — Array of unique message identifiers for an individual MMS send. Each identifier is a string that always begins with the prefix `msg_`, for example: `msg_1234567890`. When media assets are too large to fit in a single MMS and `options.multiple_messages` is set to true, the content is automatically split across multiple messages. Each split message gets its own ID, and all IDs are returned in this array. Note: When sending to audiences, you'll receive multiple response objects (one per recipient), each containing its own messageIds array. - `segments` (double, required) — Total number of segments used across the message. - `totalCost` (double, required) — Total cost of sending the message. - `sender` (string, required) — Sender's phone number in E.164 format. - `recipient` (string, required) — Recipient's phone number in E.164 format. - `status` ("queued", required) — Message is queued for delivery. ### ScheduledSendResponse - `scheduleId` (string, required) — Unique identifier for the scheduled send. This identifier is a string that always begins with the prefix `msg_sched_`, for example: `msg_sched_1234567890`. - `config` (ScheduledSendResponseConfig, required) — Configuration for the scheduled message. ### ZodError - `description` (string, required) — Human-readable summary of validation failures. - `errors` (ZodErrorErrors, required) — Structured dictionary of issues containing two main sections: - `errors`: Array of global validation errors not tied to specific fields - `properties`: Object mapping field names to their specific validation errors, where each field contains an `errors` array ### Error Standard error response returned when a request cannot be processed successfully. - `error` (string, required) — Human-readable description of the error that occurred, corresponding to the HTTP status code. ### ScheduleSchema Define when and how your message should be sent. - `sendAt` (string, required) — The date and time you want your message to be sent. - Use [ISO 8601 format](https://en.wikipedia.org/wiki/ISO_8601), for example: `2024-12-17T14:30:00Z`. Format: `YYYY-MM-DDThh:mm` (e.g., `2024-12-25T14:30`). - This time must be at least 5 minutes in the future. - The message will be scheduled based on the `timezone` you provide. - If you set a `recurrence` schedule, this is the start date and time for the recurring schedule. - `recurrence` (string, optional) — AWS cron expression for recurring schedules (6 fields). [Learn more about cron expressions](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-scheduled-rule-pattern.html). **Examples:** * `0 10 * * ? *` - Every day at 10:00 AM * `0/30 * * * ? *` - Every 30 minutes * `0 9 ? * MON-FRI *` - Every weekday at 9:00 AM * `0 12 1 * ? *` - First day of every month at noon - `timezone` (string, optional, default: UTC) — IANA timezone identifier (e.g., `America/New_York`, `UTC`). Defaults to `UTC` if not specified. - `endDate` (string, optional) — Date and time when recurring messages should stop. Format: `YYYY-MM-DDThh:mm`. Required if `recurrence` is set. ### ScheduledSendResponseConfig Configuration for the scheduled message. - `sendAt` (string, required) — When the message will be sent in ISO 8601 format. - `timezone` (string, required) — IANA timezone identifier. - `recurrence` (string, optional) — AWS cron expression used for recurring messages. - `endDate` (string, optional) — When the recurring messages stops in ISO 8601 format. ### ZodErrorErrors Structured dictionary of issues containing two main sections: - `errors`: Array of global validation errors not tied to specific fields - `properties`: Object mapping field names to their specific validation errors, where each field contains an `errors` array ## Examples ### Send MMS Response **Request** ```json { "from": "+14155164736", "mediaUrls": [ "https://fastly.picsum.photos/id/941/300/300.jpg?hmac=mDxM9PWSqRDjecwSCEpzU4bj35gqnG7yA25OL29uNv0" ], "text": "Check out this image!", "to": "+14154746461", "options": { "multiple_messages": false, "validate": true } } ``` **Response** ```json { "messageIds": [ "msg_1234567890", "msg_1234567891" ], "segments": 3, "totalCost": 0.09, "sender": "+14155164736", "recipient": "+14154746461", "status": "queued" } ``` **SDK Code** ```python Send MMS Response import requests url = "https://api.pinnacle.sh/messages/send/mms" payload = { "from": "+14155164736", "mediaUrls": ["https://fastly.picsum.photos/id/941/300/300.jpg?hmac=mDxM9PWSqRDjecwSCEpzU4bj35gqnG7yA25OL29uNv0"], "text": "Check out this image!", "to": "+14154746461", "options": { "multiple_messages": False, "validate": True } } headers = { "PINNACLE-API-KEY": "", "Content-Type": "application/json" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```javascript Send MMS Response const url = 'https://api.pinnacle.sh/messages/send/mms'; const options = { method: 'POST', headers: {'PINNACLE-API-KEY': '', 'Content-Type': 'application/json'}, body: '{"from":"+14155164736","mediaUrls":["https://fastly.picsum.photos/id/941/300/300.jpg?hmac=mDxM9PWSqRDjecwSCEpzU4bj35gqnG7yA25OL29uNv0"],"text":"Check out this image!","to":"+14154746461","options":{"multiple_messages":false,"validate":true}}' }; try { const response = await fetch(url, options); const data = await response.json(); console.log(data); } catch (error) { console.error(error); } ``` ```go Send MMS Response package main import ( "fmt" "strings" "net/http" "io" ) func main() { url := "https://api.pinnacle.sh/messages/send/mms" payload := strings.NewReader("{\n \"from\": \"+14155164736\",\n \"mediaUrls\": [\n \"https://fastly.picsum.photos/id/941/300/300.jpg?hmac=mDxM9PWSqRDjecwSCEpzU4bj35gqnG7yA25OL29uNv0\"\n ],\n \"text\": \"Check out this image!\",\n \"to\": \"+14154746461\",\n \"options\": {\n \"multiple_messages\": false,\n \"validate\": true\n }\n}") req, _ := http.NewRequest("POST", url, payload) req.Header.Add("PINNACLE-API-KEY", "") req.Header.Add("Content-Type", "application/json") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(res) fmt.Println(string(body)) } ``` ```ruby Send MMS Response require 'uri' require 'net/http' url = URI("https://api.pinnacle.sh/messages/send/mms") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = Net::HTTP::Post.new(url) request["PINNACLE-API-KEY"] = '' request["Content-Type"] = 'application/json' request.body = "{\n \"from\": \"+14155164736\",\n \"mediaUrls\": [\n \"https://fastly.picsum.photos/id/941/300/300.jpg?hmac=mDxM9PWSqRDjecwSCEpzU4bj35gqnG7yA25OL29uNv0\"\n ],\n \"text\": \"Check out this image!\",\n \"to\": \"+14154746461\",\n \"options\": {\n \"multiple_messages\": false,\n \"validate\": true\n }\n}" response = http.request(request) puts response.read_body ``` ```java Send MMS Response import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; HttpResponse response = Unirest.post("https://api.pinnacle.sh/messages/send/mms") .header("PINNACLE-API-KEY", "") .header("Content-Type", "application/json") .body("{\n \"from\": \"+14155164736\",\n \"mediaUrls\": [\n \"https://fastly.picsum.photos/id/941/300/300.jpg?hmac=mDxM9PWSqRDjecwSCEpzU4bj35gqnG7yA25OL29uNv0\"\n ],\n \"text\": \"Check out this image!\",\n \"to\": \"+14154746461\",\n \"options\": {\n \"multiple_messages\": false,\n \"validate\": true\n }\n}") .asString(); ``` ```php Send MMS Response request('POST', 'https://api.pinnacle.sh/messages/send/mms', [ 'body' => '{ "from": "+14155164736", "mediaUrls": [ "https://fastly.picsum.photos/id/941/300/300.jpg?hmac=mDxM9PWSqRDjecwSCEpzU4bj35gqnG7yA25OL29uNv0" ], "text": "Check out this image!", "to": "+14154746461", "options": { "multiple_messages": false, "validate": true } }', 'headers' => [ 'Content-Type' => 'application/json', 'PINNACLE-API-KEY' => '', ], ]); echo $response->getBody(); ``` ```csharp Send MMS Response using RestSharp; var client = new RestClient("https://api.pinnacle.sh/messages/send/mms"); var request = new RestRequest(Method.POST); request.AddHeader("PINNACLE-API-KEY", ""); request.AddHeader("Content-Type", "application/json"); request.AddParameter("application/json", "{\n \"from\": \"+14155164736\",\n \"mediaUrls\": [\n \"https://fastly.picsum.photos/id/941/300/300.jpg?hmac=mDxM9PWSqRDjecwSCEpzU4bj35gqnG7yA25OL29uNv0\"\n ],\n \"text\": \"Check out this image!\",\n \"to\": \"+14154746461\",\n \"options\": {\n \"multiple_messages\": false,\n \"validate\": true\n }\n}", ParameterType.RequestBody); IRestResponse response = client.Execute(request); ``` ```swift Send MMS Response import Foundation let headers = [ "PINNACLE-API-KEY": "", "Content-Type": "application/json" ] let parameters = [ "from": "+14155164736", "mediaUrls": ["https://fastly.picsum.photos/id/941/300/300.jpg?hmac=mDxM9PWSqRDjecwSCEpzU4bj35gqnG7yA25OL29uNv0"], "text": "Check out this image!", "to": "+14154746461", "options": [ "multiple_messages": false, "validate": true ] ] as [String : Any] let postData = JSONSerialization.data(withJSONObject: parameters, options: []) let request = NSMutableURLRequest(url: NSURL(string: "https://api.pinnacle.sh/messages/send/mms")! as URL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0) request.httpMethod = "POST" request.allHTTPHeaderFields = headers request.httpBody = postData as Data let session = URLSession.shared let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in if (error != nil) { print(error as Any) } else { let httpResponse = response as? HTTPURLResponse print(httpResponse) } }) dataTask.resume() ``` ### Scheduled Response **Request** ```json { "from": "+14155164736", "mediaUrls": [ "https://fastly.picsum.photos/id/941/300/300.jpg?hmac=mDxM9PWSqRDjecwSCEpzU4bj35gqnG7yA25OL29uNv0" ], "text": "Check out this image!", "to": "+14154746461", "options": { "multiple_messages": false, "validate": true } } ``` **Response** ```json { "scheduleId": "msg_sched_1234567890", "config": { "sendAt": "2024-08-01T09:00:00", "recurrence": "cron(0 9 * * MON-FRI *)", "timezone": "UTC", "endTime": "2024-12-31T23:59:59" } } ``` **SDK Code** ```python Scheduled Response import requests url = "https://api.pinnacle.sh/messages/send/mms" payload = { "from": "+14155164736", "mediaUrls": ["https://fastly.picsum.photos/id/941/300/300.jpg?hmac=mDxM9PWSqRDjecwSCEpzU4bj35gqnG7yA25OL29uNv0"], "text": "Check out this image!", "to": "+14154746461", "options": { "multiple_messages": False, "validate": True } } headers = { "PINNACLE-API-KEY": "", "Content-Type": "application/json" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```javascript Scheduled Response const url = 'https://api.pinnacle.sh/messages/send/mms'; const options = { method: 'POST', headers: {'PINNACLE-API-KEY': '', 'Content-Type': 'application/json'}, body: '{"from":"+14155164736","mediaUrls":["https://fastly.picsum.photos/id/941/300/300.jpg?hmac=mDxM9PWSqRDjecwSCEpzU4bj35gqnG7yA25OL29uNv0"],"text":"Check out this image!","to":"+14154746461","options":{"multiple_messages":false,"validate":true}}' }; try { const response = await fetch(url, options); const data = await response.json(); console.log(data); } catch (error) { console.error(error); } ``` ```go Scheduled Response package main import ( "fmt" "strings" "net/http" "io" ) func main() { url := "https://api.pinnacle.sh/messages/send/mms" payload := strings.NewReader("{\n \"from\": \"+14155164736\",\n \"mediaUrls\": [\n \"https://fastly.picsum.photos/id/941/300/300.jpg?hmac=mDxM9PWSqRDjecwSCEpzU4bj35gqnG7yA25OL29uNv0\"\n ],\n \"text\": \"Check out this image!\",\n \"to\": \"+14154746461\",\n \"options\": {\n \"multiple_messages\": false,\n \"validate\": true\n }\n}") req, _ := http.NewRequest("POST", url, payload) req.Header.Add("PINNACLE-API-KEY", "") req.Header.Add("Content-Type", "application/json") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(res) fmt.Println(string(body)) } ``` ```ruby Scheduled Response require 'uri' require 'net/http' url = URI("https://api.pinnacle.sh/messages/send/mms") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = Net::HTTP::Post.new(url) request["PINNACLE-API-KEY"] = '' request["Content-Type"] = 'application/json' request.body = "{\n \"from\": \"+14155164736\",\n \"mediaUrls\": [\n \"https://fastly.picsum.photos/id/941/300/300.jpg?hmac=mDxM9PWSqRDjecwSCEpzU4bj35gqnG7yA25OL29uNv0\"\n ],\n \"text\": \"Check out this image!\",\n \"to\": \"+14154746461\",\n \"options\": {\n \"multiple_messages\": false,\n \"validate\": true\n }\n}" response = http.request(request) puts response.read_body ``` ```java Scheduled Response import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; HttpResponse response = Unirest.post("https://api.pinnacle.sh/messages/send/mms") .header("PINNACLE-API-KEY", "") .header("Content-Type", "application/json") .body("{\n \"from\": \"+14155164736\",\n \"mediaUrls\": [\n \"https://fastly.picsum.photos/id/941/300/300.jpg?hmac=mDxM9PWSqRDjecwSCEpzU4bj35gqnG7yA25OL29uNv0\"\n ],\n \"text\": \"Check out this image!\",\n \"to\": \"+14154746461\",\n \"options\": {\n \"multiple_messages\": false,\n \"validate\": true\n }\n}") .asString(); ``` ```php Scheduled Response request('POST', 'https://api.pinnacle.sh/messages/send/mms', [ 'body' => '{ "from": "+14155164736", "mediaUrls": [ "https://fastly.picsum.photos/id/941/300/300.jpg?hmac=mDxM9PWSqRDjecwSCEpzU4bj35gqnG7yA25OL29uNv0" ], "text": "Check out this image!", "to": "+14154746461", "options": { "multiple_messages": false, "validate": true } }', 'headers' => [ 'Content-Type' => 'application/json', 'PINNACLE-API-KEY' => '', ], ]); echo $response->getBody(); ``` ```csharp Scheduled Response using RestSharp; var client = new RestClient("https://api.pinnacle.sh/messages/send/mms"); var request = new RestRequest(Method.POST); request.AddHeader("PINNACLE-API-KEY", ""); request.AddHeader("Content-Type", "application/json"); request.AddParameter("application/json", "{\n \"from\": \"+14155164736\",\n \"mediaUrls\": [\n \"https://fastly.picsum.photos/id/941/300/300.jpg?hmac=mDxM9PWSqRDjecwSCEpzU4bj35gqnG7yA25OL29uNv0\"\n ],\n \"text\": \"Check out this image!\",\n \"to\": \"+14154746461\",\n \"options\": {\n \"multiple_messages\": false,\n \"validate\": true\n }\n}", ParameterType.RequestBody); IRestResponse response = client.Execute(request); ``` ```swift Scheduled Response import Foundation let headers = [ "PINNACLE-API-KEY": "", "Content-Type": "application/json" ] let parameters = [ "from": "+14155164736", "mediaUrls": ["https://fastly.picsum.photos/id/941/300/300.jpg?hmac=mDxM9PWSqRDjecwSCEpzU4bj35gqnG7yA25OL29uNv0"], "text": "Check out this image!", "to": "+14154746461", "options": [ "multiple_messages": false, "validate": true ] ] as [String : Any] let postData = JSONSerialization.data(withJSONObject: parameters, options: []) let request = NSMutableURLRequest(url: NSURL(string: "https://api.pinnacle.sh/messages/send/mms")! as URL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0) request.httpMethod = "POST" request.allHTTPHeaderFields = headers request.httpBody = postData as Data let session = URLSession.shared let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in if (error != nil) { print(error as Any) } else { let httpResponse = response as? HTTPURLResponse print(httpResponse) } }) dataTask.resume() ``` > One API for RCS, iMessage, MMS, and SMS. Build, test, and scale every channel — send your first message in minutes, not weeks.