> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.pinnacle.sh/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.pinnacle.sh/_mcp/server.

# Validate RCS Message

POST https://api.pinnacle.sh/messages/validate/rcs
Content-Type: application/json

Validate RCS message content without sending it.

Reference: https://docs.pinnacle.sh/api-reference/messages/validate-rcs

## Authentication

- `PINNACLE-API-KEY` header (required) — API Key authentication via header

## Request

### Body (application/json)

This endpoint expects a RCSValidateContent.

- `RCSValidateContent`

## Response

### 200

Returns validation results.

- `total` (double, required) — Total price of this message. Calculated by multiplying the number of messages by the unit cost.
- `unit` (double, required) — Cost per message.
- `segments` (integer, required) — Total number of segments used across the message.
- `unsupportedFiles` (list of string, required) — List of unsupported media file names or URLs.

## Errors

### 400 Bad Request Error

Validation failed. The payload has missing required fields and/or invalid types.&#x20; 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.&#x20; 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.&#x20; 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.&#x20; 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

### RcsTextContent

Message containing longer text content with optional quick reply buttons.

- `text` (string, required) — Text content of the RCS message.
- `quickReplies` (list of RichButton, optional) — List of interactive quick reply buttons in the message.&#x20; **Limit:** 10 max

### Rich Media

Message containing a media file and/or text with optional quick reply buttons. See [supported media types](https://app.pinnacle.sh/supported-file-types?type=RCS-MEDIA).

- `media` (string, required) — Media file URLs to send.
- `quickReplies` (list of RichButton, optional)

### RcsCards

Message containing cards, each with its own title, subtitle, and/or buttons. Quick replies can also be added.&#x20; See (supported file types)\[[https://app.pinnacle.sh/supported-file-types?type=RCS-CARD](https://app.pinnacle.sh/supported-file-types?type=RCS-CARD)].

- `cards` (list of RcsCardsCardsItems, required) — Collection of cards attached to the message.&#x20; **Limit:** 1 to 10
- `quickReplies` (list of RichButton, optional) — List of interactive quick reply buttons in the message.&#x20; **Limit:** 10 max

### 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

### RichButton

- `type`: `openUrl` (openUrl)
  - `payload` (string, required) — The URL to open when the button is tapped. Must be a valid HTTP or HTTPS URL.
  - `title` (string, required) — Display text for the button.
  - `metadata` (string, optional) — Optional additional data to attach to this button.
  - `webviewMode` (enum, optional) — Controls how the URL is displayed when the button is tapped. **Default behavior:** If not specified, the URL opens in the device's default browser. If you're sending deeplinks, you should use this mode as it will open the deeplink in the native app if it is installed. **Available modes in order of size:** - `HALF` — Half-screen webview overlay - `TALL` — Tall webview overlay - `FULL` — Full-screen webview
    - Allowed values: `HALF`, `TALL`, `FULL`
- `type`: `call` (call)
  - `payload` (string, required) — Phone number to call in E.164 format
  - `title` (string, required) — Display text for the button.
  - `metadata` (string, optional) — Optional additional data to attach to this button.
- `type`: `trigger` (trigger)
  - `payload` (string, required) — Custom data sent to your webhook when the button is tapped. Use this to identify the user's choice.
  - `title` (string, required) — Display text for the button.
  - `metadata` (string, optional) — Optional additional data to attach to this button.
- `type`: `requestUserLocation` (requestUserLocation)
  - `title` (string, required) — Display text for the button.
  - `metadata` (string, optional) — Optional additional data to attach to this button.
- `type`: `scheduleEvent` (scheduleEvent)
  - `eventEndTime` (string, required) — End time in ISO 8601 format.
  - `eventStartTime` (string, required) — Starting time in ISO 8601 format.
  - `eventTitle` (string, required) — Title of the event.
  - `title` (string, required) — Display text for the button.
  - `eventDescription` (string, optional) — Detailed description for the calendar event.
  - `metadata` (string, optional) — Optional additional data to attach to this button.
- `type`: `sendLocation` (sendLocation)
  - `latLong` (RichButtonDiscriminatorMappingSendLocationLatLong, required) — Geographic coordinates of the location to share.
  - `title` (string, required) — Display text for the button.
  - `metadata` (string, optional) — Optional additional data to attach to this button.
  - `name` (string, optional) — Optional name or label for the location that will be displayed in the map app (e.g., "Central Park", "Home Office"). If not provided, the button title will be used as the location name.

### RcsCardsCardsItems

Individual card containing title, optional media, and action buttons.

- `title` (string, required) — Title displayed on the card.
- `buttons` (list of RichButton, optional) — While buttons resemble quick replies, they remain on screen after being clicked and are card-specific.&#x20; **Limit:** 4 max
- `media` (string, optional) — Media file URLs to send.
- `mediaHeight` (enum, optional, default: MEDIUM) — Height of the card media.&#x20; **Default:** `MEDIUM`&#x20; **Valid for:** Carousel cards and vertical standalone cards.&#x20; **Not valid for:** Horizontal standalone cards.&#x20; **Requires:** The card must include a `media` field.&#x20; **Platform:** Media height selection applies only on Android. For iOS, assume `MEDIUM`.
  - Allowed values: `SHORT`, `MEDIUM`, `TALL`
- `subtitle` (string, optional) — Secondary text displayed below the title for additional context.

### RichButtonDiscriminatorMappingSendLocationLatLong

Geographic coordinates of the location to share.

- `lat` (double, required) — Latitude coordinate in decimal degrees.
- `lng` (double, required) — Longitude coordinate in decimal degrees.

## Examples

**Request**

```json
{
  "quickReplies": [
    {
      "type": "openUrl",
      "payload": "https://www.pinnacle.sh/",
      "title": "Open Url"
    }
  ],
  "text": "Check out our website for more information!"
}
```

**Response**

```json
{
  "total": 0.035,
  "unit": 0.035,
  "segments": 1,
  "unsupportedFiles": []
}
```

**SDK Code**

```python RCS Validation
import requests

url = "https://api.pinnacle.sh/messages/validate/rcs"

payload = {
    "quickReplies": [
        {
            "type": "openUrl",
            "payload": "https://www.pinnacle.sh/",
            "title": "Open Url"
        }
    ],
    "text": "Check out our website for more information!"
}
headers = {
    "PINNACLE-API-KEY": "<apiKey>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript RCS Validation
const url = 'https://api.pinnacle.sh/messages/validate/rcs';
const options = {
  method: 'POST',
  headers: {'PINNACLE-API-KEY': '<apiKey>', 'Content-Type': 'application/json'},
  body: '{"quickReplies":[{"type":"openUrl","payload":"https://www.pinnacle.sh/","title":"Open Url"}],"text":"Check out our website for more information!"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go RCS Validation
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.pinnacle.sh/messages/validate/rcs"

	payload := strings.NewReader("{\n  \"quickReplies\": [\n    {\n      \"type\": \"openUrl\",\n      \"payload\": \"https://www.pinnacle.sh/\",\n      \"title\": \"Open Url\"\n    }\n  ],\n  \"text\": \"Check out our website for more information!\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("PINNACLE-API-KEY", "<apiKey>")
	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 RCS Validation
require 'uri'
require 'net/http'

url = URI("https://api.pinnacle.sh/messages/validate/rcs")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["PINNACLE-API-KEY"] = '<apiKey>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"quickReplies\": [\n    {\n      \"type\": \"openUrl\",\n      \"payload\": \"https://www.pinnacle.sh/\",\n      \"title\": \"Open Url\"\n    }\n  ],\n  \"text\": \"Check out our website for more information!\"\n}"

response = http.request(request)
puts response.read_body
```

```java RCS Validation
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.pinnacle.sh/messages/validate/rcs")
  .header("PINNACLE-API-KEY", "<apiKey>")
  .header("Content-Type", "application/json")
  .body("{\n  \"quickReplies\": [\n    {\n      \"type\": \"openUrl\",\n      \"payload\": \"https://www.pinnacle.sh/\",\n      \"title\": \"Open Url\"\n    }\n  ],\n  \"text\": \"Check out our website for more information!\"\n}")
  .asString();
```

```php RCS Validation
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.pinnacle.sh/messages/validate/rcs', [
  'body' => '{
  "quickReplies": [
    {
      "type": "openUrl",
      "payload": "https://www.pinnacle.sh/",
      "title": "Open Url"
    }
  ],
  "text": "Check out our website for more information!"
}',
  'headers' => [
    'Content-Type' => 'application/json',
    'PINNACLE-API-KEY' => '<apiKey>',
  ],
]);

echo $response->getBody();
```

```csharp RCS Validation
using RestSharp;

var client = new RestClient("https://api.pinnacle.sh/messages/validate/rcs");
var request = new RestRequest(Method.POST);
request.AddHeader("PINNACLE-API-KEY", "<apiKey>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"quickReplies\": [\n    {\n      \"type\": \"openUrl\",\n      \"payload\": \"https://www.pinnacle.sh/\",\n      \"title\": \"Open Url\"\n    }\n  ],\n  \"text\": \"Check out our website for more information!\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift RCS Validation
import Foundation

let headers = [
  "PINNACLE-API-KEY": "<apiKey>",
  "Content-Type": "application/json"
]
let parameters = [
  "quickReplies": [
    [
      "type": "openUrl",
      "payload": "https://www.pinnacle.sh/",
      "title": "Open Url"
    ]
  ],
  "text": "Check out our website for more information!"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.pinnacle.sh/messages/validate/rcs")! 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()
```