> 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/get/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.pinnacle.sh/_mcp/server. # Get Message by ID GET https://api.pinnacle.sh/messages/{id} Retrieve a previously sent message. Reference: https://docs.pinnacle.sh/api-reference/messages/get ## Authentication - `PINNACLE-API-KEY` header (required) — API Key authentication via header ## Request ### Path parameters - `id` (string, required) — Unique identifier of the message. This identifier is a string that always begins with the prefix `msg_`, for example: `msg_1234567890`. ## Response ### 200 Successfully retrieved the message. - `content` (MessageContentType, required) — Content type of the message. - `cost` (double, required, nullable) — Total cost charged for sending the message. Null means the message incurred no cost or has not been charged yet. - `deliveredAt` (string, required, nullable) — Timestamp indicating when the message was successfully delivered to the recipient. Null indicates the message has not yet been delivered. - `error` (string, required, nullable) — Detailed explanation of any errors that occurred while delivering the message. Null indicates no errors. - `id` (string, required) — Unique identifier of the message. This identifier is a string that always begins with the prefix `msg_`, for example: `msg_1234567890`. - `method` (enum, required) — Method used to send the message. - Allowed values: `API`, `SDK`, `OTHER` - `numSegments` (integer, required) — Number of segments the message was split into for delivery. - `receiver` (string, required) — Phone number that received the message in E.164 format. - `sender` (string, required) — Phone number or agent that sent the message. - `sentAt` (string, required, nullable) — Timestamp indicating when the message was submitted for delivery. Null indicates the message is still in the queue. - `status` (enum, required) — Current status of the message. - Allowed values: `QUEUED`, `PENDING`, `SENT`, `SEND_FAILED`, `DELIVERED`, `DELIVERY_FAILED`, `RECEIVED`, `READ`, `FALLBACK_SENT` - `type` (enum, required) — Delivery protocol used for sending this message. - Allowed values: `SMS`, `MMS`, `RCS` ## Errors ### 400 Bad Request Error Validation failed. The payload has missing required fields and/or invalid types. See [https://zod.dev/error-formatting](https://zod.dev/error-formatting) for more information. - `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 ### 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. ### 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. ## Types ### MessageContentType Content type of the message. ### 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 ### SMSContent SMS message containing plain text only. - `text` (string, required) — Message content. ### 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. ## Examples ### SMS Response **Response** ```json { "content": { "text": "Hello from Pinnacle" }, "cost": 10, "deliveredAt": null, "error": "{\"message\": \"Error: Timeout occurred\"}", "id": "msg_1234567890", "method": "API", "numSegments": 1, "receiver": "+1415654321", "sender": "+1415567890", "sentAt": "2025-06-18T21:27:13.809", "status": "PENDING", "type": "SMS" } ``` **SDK Code** ```python SMS Response import requests url = "https://api.pinnacle.sh/messages/msg_1234567890" headers = {"PINNACLE-API-KEY": ""} response = requests.get(url, headers=headers) print(response.json()) ``` ```javascript SMS Response const url = 'https://api.pinnacle.sh/messages/msg_1234567890'; const options = {method: 'GET', headers: {'PINNACLE-API-KEY': ''}}; try { const response = await fetch(url, options); const data = await response.json(); console.log(data); } catch (error) { console.error(error); } ``` ```go SMS Response package main import ( "fmt" "net/http" "io" ) func main() { url := "https://api.pinnacle.sh/messages/msg_1234567890" req, _ := http.NewRequest("GET", url, nil) req.Header.Add("PINNACLE-API-KEY", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(res) fmt.Println(string(body)) } ``` ```ruby SMS Response require 'uri' require 'net/http' url = URI("https://api.pinnacle.sh/messages/msg_1234567890") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = Net::HTTP::Get.new(url) request["PINNACLE-API-KEY"] = '' response = http.request(request) puts response.read_body ``` ```java SMS Response import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; HttpResponse response = Unirest.get("https://api.pinnacle.sh/messages/msg_1234567890") .header("PINNACLE-API-KEY", "") .asString(); ``` ```php SMS Response request('GET', 'https://api.pinnacle.sh/messages/msg_1234567890', [ 'headers' => [ 'PINNACLE-API-KEY' => '', ], ]); echo $response->getBody(); ``` ```csharp SMS Response using RestSharp; var client = new RestClient("https://api.pinnacle.sh/messages/msg_1234567890"); var request = new RestRequest(Method.GET); request.AddHeader("PINNACLE-API-KEY", ""); IRestResponse response = client.Execute(request); ``` ```swift SMS Response import Foundation let headers = ["PINNACLE-API-KEY": ""] let request = NSMutableURLRequest(url: NSURL(string: "https://api.pinnacle.sh/messages/msg_1234567890")! as URL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0) request.httpMethod = "GET" request.allHTTPHeaderFields = headers 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() ``` ### MMS Response **Response** ```json { "content": { "mediaUrls": [ "https://agent-logos.storage.googleapis.com/_/m0bk9gvlDunZEw1krfruZmw3" ], "text": "Check out our website for more information!" }, "cost": 30, "deliveredAt": null, "error": "{\"message\": \"Error: Timeout occurred\"}", "id": "msg_1234567890", "method": "SDK", "numSegments": 1, "receiver": "+1415654321", "sender": "+1415567890", "sentAt": "2025-08-08T22:05:23.291", "status": "PENDING", "type": "MMS" } ``` **SDK Code** ```python MMS Response import requests url = "https://api.pinnacle.sh/messages/msg_1234567890" headers = {"PINNACLE-API-KEY": ""} response = requests.get(url, headers=headers) print(response.json()) ``` ```javascript MMS Response const url = 'https://api.pinnacle.sh/messages/msg_1234567890'; const options = {method: 'GET', headers: {'PINNACLE-API-KEY': ''}}; try { const response = await fetch(url, options); const data = await response.json(); console.log(data); } catch (error) { console.error(error); } ``` ```go MMS Response package main import ( "fmt" "net/http" "io" ) func main() { url := "https://api.pinnacle.sh/messages/msg_1234567890" req, _ := http.NewRequest("GET", url, nil) req.Header.Add("PINNACLE-API-KEY", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(res) fmt.Println(string(body)) } ``` ```ruby MMS Response require 'uri' require 'net/http' url = URI("https://api.pinnacle.sh/messages/msg_1234567890") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = Net::HTTP::Get.new(url) request["PINNACLE-API-KEY"] = '' response = http.request(request) puts response.read_body ``` ```java MMS Response import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; HttpResponse response = Unirest.get("https://api.pinnacle.sh/messages/msg_1234567890") .header("PINNACLE-API-KEY", "") .asString(); ``` ```php MMS Response request('GET', 'https://api.pinnacle.sh/messages/msg_1234567890', [ 'headers' => [ 'PINNACLE-API-KEY' => '', ], ]); echo $response->getBody(); ``` ```csharp MMS Response using RestSharp; var client = new RestClient("https://api.pinnacle.sh/messages/msg_1234567890"); var request = new RestRequest(Method.GET); request.AddHeader("PINNACLE-API-KEY", ""); IRestResponse response = client.Execute(request); ``` ```swift MMS Response import Foundation let headers = ["PINNACLE-API-KEY": ""] let request = NSMutableURLRequest(url: NSURL(string: "https://api.pinnacle.sh/messages/msg_1234567890")! as URL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0) request.httpMethod = "GET" request.allHTTPHeaderFields = headers 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() ``` ### RCS Response **Response** ```json { "content": { "cards": [ { "buttons": [ { "type": "openUrl", "payload": "https://www.pinnacle.sh/", "title": "Visit US" }, { "payload": "+14150578591", "title": "Call Us", "type": "call" }, { "eventEndTime": "2025-12-12T11:00:00Z", "eventStartTime": "2025-12-12T10:00:00Z", "eventTitle": "RCS Exploration", "title": "Pinnacle Workshop", "type": "scheduleEvent" } ], "media": { "fullPath": "vault/sample-image.webp", "mimeType": "image/webp", "url": "https://example.com/media/sample-image.webp" }, "subtitle": "OpenUrl", "title": "See Website" } ], "quickReplies": [ { "type": "openUrl", "payload": "https://www.pinnacle.sh/", "title": "Visit US" }, { "payload": "+14150578591", "title": "Quick Call", "type": "call" }, { "eventEndTime": "2025-12-12T13:00:00Z", "eventStartTime": "2025-12-12T12:00:00Z", "eventTitle": "Pinnacle Workshop", "title": "Add Event", "type": "scheduleEvent" } ] }, "cost": 30, "deliveredAt": "2025-08-05T18:51:00.591", "error": "{\"message\": \"Error: Timeout occurred\"}", "id": "msg_1234567890", "method": "OTHER", "numSegments": 1, "receiver": "+1415654321", "sender": "+1415567890", "sentAt": "2025-08-05T18:50:55.912", "status": "DELIVERED", "type": "RCS" } ``` **SDK Code** ```python RCS Response import requests url = "https://api.pinnacle.sh/messages/msg_1234567890" headers = {"PINNACLE-API-KEY": ""} response = requests.get(url, headers=headers) print(response.json()) ``` ```javascript RCS Response const url = 'https://api.pinnacle.sh/messages/msg_1234567890'; const options = {method: 'GET', headers: {'PINNACLE-API-KEY': ''}}; try { const response = await fetch(url, options); const data = await response.json(); console.log(data); } catch (error) { console.error(error); } ``` ```go RCS Response package main import ( "fmt" "net/http" "io" ) func main() { url := "https://api.pinnacle.sh/messages/msg_1234567890" req, _ := http.NewRequest("GET", url, nil) req.Header.Add("PINNACLE-API-KEY", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(res) fmt.Println(string(body)) } ``` ```ruby RCS Response require 'uri' require 'net/http' url = URI("https://api.pinnacle.sh/messages/msg_1234567890") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = Net::HTTP::Get.new(url) request["PINNACLE-API-KEY"] = '' response = http.request(request) puts response.read_body ``` ```java RCS Response import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; HttpResponse response = Unirest.get("https://api.pinnacle.sh/messages/msg_1234567890") .header("PINNACLE-API-KEY", "") .asString(); ``` ```php RCS Response request('GET', 'https://api.pinnacle.sh/messages/msg_1234567890', [ 'headers' => [ 'PINNACLE-API-KEY' => '', ], ]); echo $response->getBody(); ``` ```csharp RCS Response using RestSharp; var client = new RestClient("https://api.pinnacle.sh/messages/msg_1234567890"); var request = new RestRequest(Method.GET); request.AddHeader("PINNACLE-API-KEY", ""); IRestResponse response = client.Execute(request); ``` ```swift RCS Response import Foundation let headers = ["PINNACLE-API-KEY": ""] let request = NSMutableURLRequest(url: NSURL(string: "https://api.pinnacle.sh/messages/msg_1234567890")! as URL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0) request.httpMethod = "GET" request.allHTTPHeaderFields = headers 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() ``` ### Inbound Response **Response** ```json { "content": { "text": "string" }, "cost": 30, "deliveredAt": "2025-08-05T18:51:00.591", "error": "{\"value\":[]}", "id": "msg_1234567890", "method": "OTHER", "numSegments": 1, "receiver": "+1415654321", "sender": "+1415567890", "sentAt": "2025-08-05T18:50:55.912", "status": "DELIVERED", "type": "RCS" } ``` **SDK Code** ```python Inbound Response import requests url = "https://api.pinnacle.sh/messages/msg_1234567890" headers = {"PINNACLE-API-KEY": ""} response = requests.get(url, headers=headers) print(response.json()) ``` ```javascript Inbound Response const url = 'https://api.pinnacle.sh/messages/msg_1234567890'; const options = {method: 'GET', headers: {'PINNACLE-API-KEY': ''}}; try { const response = await fetch(url, options); const data = await response.json(); console.log(data); } catch (error) { console.error(error); } ``` ```go Inbound Response package main import ( "fmt" "net/http" "io" ) func main() { url := "https://api.pinnacle.sh/messages/msg_1234567890" req, _ := http.NewRequest("GET", url, nil) req.Header.Add("PINNACLE-API-KEY", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(res) fmt.Println(string(body)) } ``` ```ruby Inbound Response require 'uri' require 'net/http' url = URI("https://api.pinnacle.sh/messages/msg_1234567890") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = Net::HTTP::Get.new(url) request["PINNACLE-API-KEY"] = '' response = http.request(request) puts response.read_body ``` ```java Inbound Response import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; HttpResponse response = Unirest.get("https://api.pinnacle.sh/messages/msg_1234567890") .header("PINNACLE-API-KEY", "") .asString(); ``` ```php Inbound Response request('GET', 'https://api.pinnacle.sh/messages/msg_1234567890', [ 'headers' => [ 'PINNACLE-API-KEY' => '', ], ]); echo $response->getBody(); ``` ```csharp Inbound Response using RestSharp; var client = new RestClient("https://api.pinnacle.sh/messages/msg_1234567890"); var request = new RestRequest(Method.GET); request.AddHeader("PINNACLE-API-KEY", ""); IRestResponse response = client.Execute(request); ``` ```swift Inbound Response import Foundation let headers = ["PINNACLE-API-KEY": ""] let request = NSMutableURLRequest(url: NSURL(string: "https://api.pinnacle.sh/messages/msg_1234567890")! as URL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0) request.httpMethod = "GET" request.allHTTPHeaderFields = headers 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() ``` ### RCS with Fallback Sent **Response** ```json { "content": { "quickReplies": [], "text": "Check out our latest offers!" }, "cost": 0, "deliveredAt": null, "error": null, "id": "msg_rcs123456", "method": "API", "numSegments": 0, "receiver": "+1415654321", "sender": "agent_pinnacle", "sentAt": "2025-08-05T18:50:55.912", "status": "FALLBACK_SENT", "type": "RCS" } ``` **SDK Code** ```python RCS with Fallback Sent import requests url = "https://api.pinnacle.sh/messages/msg_1234567890" headers = {"PINNACLE-API-KEY": ""} response = requests.get(url, headers=headers) print(response.json()) ``` ```javascript RCS with Fallback Sent const url = 'https://api.pinnacle.sh/messages/msg_1234567890'; const options = {method: 'GET', headers: {'PINNACLE-API-KEY': ''}}; try { const response = await fetch(url, options); const data = await response.json(); console.log(data); } catch (error) { console.error(error); } ``` ```go RCS with Fallback Sent package main import ( "fmt" "net/http" "io" ) func main() { url := "https://api.pinnacle.sh/messages/msg_1234567890" req, _ := http.NewRequest("GET", url, nil) req.Header.Add("PINNACLE-API-KEY", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(res) fmt.Println(string(body)) } ``` ```ruby RCS with Fallback Sent require 'uri' require 'net/http' url = URI("https://api.pinnacle.sh/messages/msg_1234567890") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = Net::HTTP::Get.new(url) request["PINNACLE-API-KEY"] = '' response = http.request(request) puts response.read_body ``` ```java RCS with Fallback Sent import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; HttpResponse response = Unirest.get("https://api.pinnacle.sh/messages/msg_1234567890") .header("PINNACLE-API-KEY", "") .asString(); ``` ```php RCS with Fallback Sent request('GET', 'https://api.pinnacle.sh/messages/msg_1234567890', [ 'headers' => [ 'PINNACLE-API-KEY' => '', ], ]); echo $response->getBody(); ``` ```csharp RCS with Fallback Sent using RestSharp; var client = new RestClient("https://api.pinnacle.sh/messages/msg_1234567890"); var request = new RestRequest(Method.GET); request.AddHeader("PINNACLE-API-KEY", ""); IRestResponse response = client.Execute(request); ``` ```swift RCS with Fallback Sent import Foundation let headers = ["PINNACLE-API-KEY": ""] let request = NSMutableURLRequest(url: NSURL(string: "https://api.pinnacle.sh/messages/msg_1234567890")! as URL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0) request.httpMethod = "GET" request.allHTTPHeaderFields = headers 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.