> 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/blast-mms/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.pinnacle.sh/_mcp/server. # Blast MMS to Audience POST https://api.pinnacle.sh/messages/blast/mms Content-Type: application/json Send an MMS message to all contacts in an audience. Messages are distributed evenly across the provided sender phone numbers. Use the optional `schedule` parameter in `options` to schedule the blast for future delivery. When scheduled, the response will contain a `scheduleId` instead of blast details. Reference: https://docs.pinnacle.sh/api-reference/messages/blast-mms ## Authentication - `PINNACLE-API-KEY` header (required) — API Key authentication via header ## Request ### Body (application/json) This endpoint expects a BlastMmsRequest. - `audienceId` (string, required) — The audience ID to send the blast to. This identifier is a string that always begins with the prefix `aud_`, for example: `aud_abc123`. You can create an audience via [the dashboard](https://app.pinnacle.sh/dashboard/audiences) or [API](/api-reference/audiences/create). - `senders` (list of string, required) — Array of phone numbers to send from in E.164 format. Messages will be distributed evenly across these senders. > **Note:** Sandbox numbers cannot be used for blasts. **Limit:** 1 min - `message` (MMSContent, required) — Message with text and/or media files from a phone number. - `options` (BlastMmsOptions, optional) — Additional settings to customize MMS blast delivery. ## Response ### 200 Successfully queued or scheduled the MMS blast. * **Immediate blast**: Returns blast details including total recipients, messages, segments, and cost. * **Scheduled blast**: Returns a `scheduleId` and the schedule configuration. - `messages_blast_mms_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. - `BlastMmsToAudienceRequestBadRequestError` ### 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. ### 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. ## Types ### MMSContent Message with text and/or media files from a phone number. - `mediaUrls` (list of string, required) — URLs of media files in this message. See [supported media types](https://app.pinnacle.sh/supported-file-types?type=MMS). - `text` (string, optional) — Text content that accompanies the media files. ### BlastMmsOptions Additional settings to customize MMS blast delivery. - `validate` (boolean, optional, default: false) — Set to true to validate the message before sending. If validation fails, the blast is not sent. - `schedule` (ScheduleSchema, optional) — Define when and how your message should be sent. ### BlastResponse Response containing details about the scheduled blast. - `blastId` (string, required) — Unique identifier for the blast. This identifier is a string that always begins with the prefix `blast_`, for example: `blast_1234567890`. - `audienceId` (string, required) — The audience ID the blast was sent to. This identifier is a string that always begins with the prefix `aud_`, for example: `aud_abc123`. - `totalRecipients` (integer, required) — Total number of recipients in the audience. - `totalMessages` (integer, required) — Total number of messages to be sent. - `totalSegments` (integer, required) — Total number of message segments across all messages. - `totalCost` (double, required) — Total cost of the blast. For RCS blasts with a fallback configured, this reflects the actual mix of RCS and SMS/MMS pricing based on each recipient's RCS capability. For more details check the [Transactions page](https://app.pinnacle.sh/dashboard/settings/billing/transactions) and the [Audiences page](https://app.pinnacle.sh/dashboard/audiences) to see blasts. ### ScheduledBlastResponse Response returned when a blast is scheduled for future delivery. - `scheduleId` (string, required) — Unique identifier for the scheduled blast. This identifier is a string that always begins with the prefix `msg_sched_`, for example: `msg_sched_xxxxx`. - `config` (ScheduledBlastResponseConfig, required) — The schedule configuration for the blast. ### 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. ### ScheduledBlastResponseConfig The schedule configuration for the blast. - `sendAt` (string, optional) — When the first message will be sent. - `recurrence` (string, optional) — AWS cron expression for recurring schedules. - `timezone` (string, optional) — IANA timezone identifier. - `endDate` (string, optional) — When recurring schedules will stop. ### 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 ### Immediate Blast Response **Request** ```json { "audienceId": "aud_abc123", "senders": [ "+14155164736", "+14155164737" ], "message": { "mediaUrls": [ "https://fastly.picsum.photos/id/941/300/300.jpg" ], "text": "Check out this image!" }, "options": { "validate": true } } ``` **Response** ```json { "blastId": "blast_1234567890", "audienceId": "aud_abc123", "totalRecipients": 500, "totalMessages": 500, "totalSegments": 1000, "totalCost": 30 } ``` **SDK Code** ```python Immediate Blast Response import requests url = "https://api.pinnacle.sh/messages/blast/mms" payload = { "audienceId": "aud_abc123", "senders": ["+14155164736", "+14155164737"], "message": { "mediaUrls": ["https://fastly.picsum.photos/id/941/300/300.jpg"], "text": "Check out this image!" }, "options": { "validate": True } } headers = { "PINNACLE-API-KEY": "", "Content-Type": "application/json" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```javascript Immediate Blast Response const url = 'https://api.pinnacle.sh/messages/blast/mms'; const options = { method: 'POST', headers: {'PINNACLE-API-KEY': '', 'Content-Type': 'application/json'}, body: '{"audienceId":"aud_abc123","senders":["+14155164736","+14155164737"],"message":{"mediaUrls":["https://fastly.picsum.photos/id/941/300/300.jpg"],"text":"Check out this image!"},"options":{"validate":true}}' }; try { const response = await fetch(url, options); const data = await response.json(); console.log(data); } catch (error) { console.error(error); } ``` ```go Immediate Blast Response package main import ( "fmt" "strings" "net/http" "io" ) func main() { url := "https://api.pinnacle.sh/messages/blast/mms" payload := strings.NewReader("{\n \"audienceId\": \"aud_abc123\",\n \"senders\": [\n \"+14155164736\",\n \"+14155164737\"\n ],\n \"message\": {\n \"mediaUrls\": [\n \"https://fastly.picsum.photos/id/941/300/300.jpg\"\n ],\n \"text\": \"Check out this image!\"\n },\n \"options\": {\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 Immediate Blast Response require 'uri' require 'net/http' url = URI("https://api.pinnacle.sh/messages/blast/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 \"audienceId\": \"aud_abc123\",\n \"senders\": [\n \"+14155164736\",\n \"+14155164737\"\n ],\n \"message\": {\n \"mediaUrls\": [\n \"https://fastly.picsum.photos/id/941/300/300.jpg\"\n ],\n \"text\": \"Check out this image!\"\n },\n \"options\": {\n \"validate\": true\n }\n}" response = http.request(request) puts response.read_body ``` ```java Immediate Blast Response import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; HttpResponse response = Unirest.post("https://api.pinnacle.sh/messages/blast/mms") .header("PINNACLE-API-KEY", "") .header("Content-Type", "application/json") .body("{\n \"audienceId\": \"aud_abc123\",\n \"senders\": [\n \"+14155164736\",\n \"+14155164737\"\n ],\n \"message\": {\n \"mediaUrls\": [\n \"https://fastly.picsum.photos/id/941/300/300.jpg\"\n ],\n \"text\": \"Check out this image!\"\n },\n \"options\": {\n \"validate\": true\n }\n}") .asString(); ``` ```php Immediate Blast Response request('POST', 'https://api.pinnacle.sh/messages/blast/mms', [ 'body' => '{ "audienceId": "aud_abc123", "senders": [ "+14155164736", "+14155164737" ], "message": { "mediaUrls": [ "https://fastly.picsum.photos/id/941/300/300.jpg" ], "text": "Check out this image!" }, "options": { "validate": true } }', 'headers' => [ 'Content-Type' => 'application/json', 'PINNACLE-API-KEY' => '', ], ]); echo $response->getBody(); ``` ```csharp Immediate Blast Response using RestSharp; var client = new RestClient("https://api.pinnacle.sh/messages/blast/mms"); var request = new RestRequest(Method.POST); request.AddHeader("PINNACLE-API-KEY", ""); request.AddHeader("Content-Type", "application/json"); request.AddParameter("application/json", "{\n \"audienceId\": \"aud_abc123\",\n \"senders\": [\n \"+14155164736\",\n \"+14155164737\"\n ],\n \"message\": {\n \"mediaUrls\": [\n \"https://fastly.picsum.photos/id/941/300/300.jpg\"\n ],\n \"text\": \"Check out this image!\"\n },\n \"options\": {\n \"validate\": true\n }\n}", ParameterType.RequestBody); IRestResponse response = client.Execute(request); ``` ```swift Immediate Blast Response import Foundation let headers = [ "PINNACLE-API-KEY": "", "Content-Type": "application/json" ] let parameters = [ "audienceId": "aud_abc123", "senders": ["+14155164736", "+14155164737"], "message": [ "mediaUrls": ["https://fastly.picsum.photos/id/941/300/300.jpg"], "text": "Check out this image!" ], "options": ["validate": true] ] as [String : Any] let postData = JSONSerialization.data(withJSONObject: parameters, options: []) let request = NSMutableURLRequest(url: NSURL(string: "https://api.pinnacle.sh/messages/blast/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 Blast Response **Request** ```json { "audienceId": "aud_abc123", "senders": [ "+14155164736", "+14155164737" ], "message": { "mediaUrls": [ "https://fastly.picsum.photos/id/941/300/300.jpg" ], "text": "Check out this image!" }, "options": { "validate": true } } ``` **Response** ```json { "scheduleId": "msg_sched_xxxxx", "config": { "sendAt": "2024-12-25T10:00", "timezone": "America/New_York" } } ``` **SDK Code** ```python Scheduled Blast Response import requests url = "https://api.pinnacle.sh/messages/blast/mms" payload = { "audienceId": "aud_abc123", "senders": ["+14155164736", "+14155164737"], "message": { "mediaUrls": ["https://fastly.picsum.photos/id/941/300/300.jpg"], "text": "Check out this image!" }, "options": { "validate": True } } headers = { "PINNACLE-API-KEY": "", "Content-Type": "application/json" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```javascript Scheduled Blast Response const url = 'https://api.pinnacle.sh/messages/blast/mms'; const options = { method: 'POST', headers: {'PINNACLE-API-KEY': '', 'Content-Type': 'application/json'}, body: '{"audienceId":"aud_abc123","senders":["+14155164736","+14155164737"],"message":{"mediaUrls":["https://fastly.picsum.photos/id/941/300/300.jpg"],"text":"Check out this image!"},"options":{"validate":true}}' }; try { const response = await fetch(url, options); const data = await response.json(); console.log(data); } catch (error) { console.error(error); } ``` ```go Scheduled Blast Response package main import ( "fmt" "strings" "net/http" "io" ) func main() { url := "https://api.pinnacle.sh/messages/blast/mms" payload := strings.NewReader("{\n \"audienceId\": \"aud_abc123\",\n \"senders\": [\n \"+14155164736\",\n \"+14155164737\"\n ],\n \"message\": {\n \"mediaUrls\": [\n \"https://fastly.picsum.photos/id/941/300/300.jpg\"\n ],\n \"text\": \"Check out this image!\"\n },\n \"options\": {\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 Blast Response require 'uri' require 'net/http' url = URI("https://api.pinnacle.sh/messages/blast/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 \"audienceId\": \"aud_abc123\",\n \"senders\": [\n \"+14155164736\",\n \"+14155164737\"\n ],\n \"message\": {\n \"mediaUrls\": [\n \"https://fastly.picsum.photos/id/941/300/300.jpg\"\n ],\n \"text\": \"Check out this image!\"\n },\n \"options\": {\n \"validate\": true\n }\n}" response = http.request(request) puts response.read_body ``` ```java Scheduled Blast Response import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; HttpResponse response = Unirest.post("https://api.pinnacle.sh/messages/blast/mms") .header("PINNACLE-API-KEY", "") .header("Content-Type", "application/json") .body("{\n \"audienceId\": \"aud_abc123\",\n \"senders\": [\n \"+14155164736\",\n \"+14155164737\"\n ],\n \"message\": {\n \"mediaUrls\": [\n \"https://fastly.picsum.photos/id/941/300/300.jpg\"\n ],\n \"text\": \"Check out this image!\"\n },\n \"options\": {\n \"validate\": true\n }\n}") .asString(); ``` ```php Scheduled Blast Response request('POST', 'https://api.pinnacle.sh/messages/blast/mms', [ 'body' => '{ "audienceId": "aud_abc123", "senders": [ "+14155164736", "+14155164737" ], "message": { "mediaUrls": [ "https://fastly.picsum.photos/id/941/300/300.jpg" ], "text": "Check out this image!" }, "options": { "validate": true } }', 'headers' => [ 'Content-Type' => 'application/json', 'PINNACLE-API-KEY' => '', ], ]); echo $response->getBody(); ``` ```csharp Scheduled Blast Response using RestSharp; var client = new RestClient("https://api.pinnacle.sh/messages/blast/mms"); var request = new RestRequest(Method.POST); request.AddHeader("PINNACLE-API-KEY", ""); request.AddHeader("Content-Type", "application/json"); request.AddParameter("application/json", "{\n \"audienceId\": \"aud_abc123\",\n \"senders\": [\n \"+14155164736\",\n \"+14155164737\"\n ],\n \"message\": {\n \"mediaUrls\": [\n \"https://fastly.picsum.photos/id/941/300/300.jpg\"\n ],\n \"text\": \"Check out this image!\"\n },\n \"options\": {\n \"validate\": true\n }\n}", ParameterType.RequestBody); IRestResponse response = client.Execute(request); ``` ```swift Scheduled Blast Response import Foundation let headers = [ "PINNACLE-API-KEY": "", "Content-Type": "application/json" ] let parameters = [ "audienceId": "aud_abc123", "senders": ["+14155164736", "+14155164737"], "message": [ "mediaUrls": ["https://fastly.picsum.photos/id/941/300/300.jpg"], "text": "Check out this image!" ], "options": ["validate": true] ] as [String : Any] let postData = JSONSerialization.data(withJSONObject: parameters, options: []) let request = NSMutableURLRequest(url: NSURL(string: "https://api.pinnacle.sh/messages/blast/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.