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

# Send RCS Message

> Embed an interactive RCS message composer into your application

The RCS message embed enables customers to preview and send RCS messages directly from your website. Perfect for sending demos.

![Send RCS Message](https://pncl.to/Q0srJ3J74209U2Sp5VfIA3xJj29e5z)

## Step 1: Backend

Create an endpoint that requests a signed token from Pinnacle. Configure the display message and send permissions.

#### server.ts

```typescript
import 'dotenv/config';
import express from 'express';

const app = express();
app.use(express.json());

app.get('/api/get-send-rcs-message-token', async (req, res) => {
  const response = await fetch('https://api.pinnacle.sh/embed/get-token', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'pinnacle-api-key': process.env.PINNACLE_API_KEY!
    },
    body: JSON.stringify({
      // required
      agentId: process.env.AGENT_ID!,
      scopes: ['MESSAGES.SEND'],
      configuredMessage: {
        // required
        agentName: "Your Brand",
        agentIconUrl: "https://example.com/icon.png",
        title: "Message Title",
        subtitle: "Message Subtitle",
        basicText: "Your message content",
        consentText: "Message and data rates may apply.",
        termsUrl: "https://example.com/terms",
        privacyUrl: "https://example.com/privacy",

        // optional
        imageUrl: "https://example.com/image.jpg",
        videoUrl: "https://example.com/video.mp4",
        pdfUrl: "https://example.com/document.pdf",
        pdfSize: 10,
        quickReplies: [
          { type: 'trigger', title: 'Shop Now', payload: 'shop_action' },
          { type: 'openUrl', title: 'Learn More', payload: 'https://example.com' },
          { type: 'call', title: 'Call Support', payload: '+14155551234' },
          {
            type: 'sendLocation',
            title: 'Get Directions',
            latLong: { lat: 37.7749, lng: -122.4194 },
            name: 'Store Location'
          },
          { type: 'requestUserLocation', title: 'Find Nearby' },
          {
            type: 'scheduleEvent',
            title: 'Add to Calendar',
            eventStartTime: '2025-02-21T10:00:00Z',
            eventEndTime: '2025-02-21T11:00:00Z',
            eventTitle: 'Product Demo',
          }
        ]
      }
    })
  });

  const { signedToken } = await response.json();
  res.json({ signedToken });
});

app.listen(8080, () => {
  console.log('Server running at http://localhost:8080');
});
```

#### package.json

```json
{
  "name": "rcs-embed-demo",
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "dev": "tsx watch server.ts",
    "start": "tsx server.ts"
  },
  "dependencies": {
    "dotenv": "^16.4.7",
    "express": "^5.2.1"
  },
  "devDependencies": {
    "@types/express": "^5.0.6",
    "@types/node": "^20",
    "tsx": "^4.19.3",
    "typescript": "^5"
  }
}
```

#### .env.example

```bash
# https://app.pinnacle.sh/dashboard/development/api-keys
PINNACLE_API_KEY=pnclk_your_api_key_here

# https://app.pinnacle.sh/dashboard/agents
AGENT_ID=agent_XXXXXXXXXXXX
```

### Schema

| Field               | Type       | Required | Description                              |
| ------------------- | ---------- | -------- | ---------------------------------------- |
| `agentId`           | `string`   | Yes      | Your RCS agent ID                        |
| `configuredMessage` | `object`   | Yes      | Message content and layout configuration |
| `scopes`            | `string[]` | Yes      | Permissions granted to the token         |

\


#### configuredMessage

| Field          | Type           | Required | Description                                                                                             |
| -------------- | -------------- | -------- | ------------------------------------------------------------------------------------------------------- |
| `agentName`    | `string`       | Yes      | Display name for your RCS agent                                                                         |
| `agentIconUrl` | `string`       | Yes      | URL to your agent's icon image                                                                          |
| `title`        | `string`       | Yes      | Card title for rich messages                                                                            |
| `subtitle`     | `string`       | Yes      | Supporting text under the title                                                                         |
| `basicText`    | `string`       | Yes      | Plain text content for simple messages                                                                  |
| `consentText`  | `string`       | Yes      | Legal consent disclosure text                                                                           |
| `termsUrl`     | `string`       | Yes      | Link to your terms of service                                                                           |
| `privacyUrl`   | `string`       | Yes      | Link to your privacy policy                                                                             |
| `imageUrl`     | `string`       | No       | Image URL for rich media messages                                                                       |
| `videoUrl`     | `string`       | No       | Video URL for rich media messages                                                                       |
| `pdfUrl`       | `string`       | No       | PDF URL for rich media messages                                                                         |
| `pdfSize`      | `number`       | No       | PDF file size in KB                                                                                     |
| `quickReplies` | `RichButton[]` | No       | Array of [RichButton](/api-reference/messages/send-rcs#request.body.Text.quickReplies) objects (max 10) |

> **Info**
>
> Maximum 10 quick replies per message. See the [RCS API reference](/api-reference/messages/send-rcs#request.body.Text.quickReplies) for all available quick reply types.

#### scopes

| Scopes          | Description                     |
| --------------- | ------------------------------- |
| `MESSAGES.SEND` | Permission to send RCS messages |

## Step 2: Frontend

Add the iframe to your page. Subscribe to the `message` event to listen for `RCS_WIDGET_READY`, then send `INIT_SEND_DEMO` with your signed token to initialize the embed.

```html
<!-- Other page content -->

<iframe
  id="send_rcs"
  src="https://embed.pinnacle.sh/embed/v2/send-rcs-message"
  style="width: 100vw; height: 100vh; border: none;">
</iframe>

<!-- Other page content -->

<script>
  const iframe = document.getElementById('send_rcs');

  window.addEventListener('message', async (event) => {
    if (event.origin !== 'https://embed.pinnacle.sh') return;

    if (event.data.type === 'RCS_WIDGET_READY') {
      // Fetch token from your backend
      const res = await fetch('/api/get-send-rcs-message-token');
      const { signedToken } = await res.json();

      // Initialize the widget
      iframe.contentWindow.postMessage({
        type: 'INIT_SEND_DEMO',             // required
        signedToken: signedToken,           // required
        primaryColor: '#16a34a'
      }, 'https://embed.pinnacle.sh');
    }
  });
</script>

<!-- Other page content -->
```

### Events

| Field              | Type          | Description                                                  |
| ------------------ | ------------- | ------------------------------------------------------------ |
| `INIT_SEND_DEMO`   | `postMessage` | Send signed token and configuration to initialize the widget |
| `RCS_WIDGET_READY` | `event`       | Iframe has loaded and is ready to receive configuration      |

\


#### INIT\_SEND\_DEMO

| Field          | Type               | Required | Description                                          |
| -------------- | ------------------ | -------- | ---------------------------------------------------- |
| `type`         | `"INIT_SEND_DEMO"` | Yes      | Message type identifier                              |
| `signedToken`  | `string`           | Yes      | JWT token from your backend                          |
| `primaryColor` | `string`           | No       | Primary color for the widget (defaults to `#16a34a`) |

#### RCS\_WIDGET\_READY

Emitted by the iframe when it has loaded and is ready to receive configuration. Listen for this event before sending `INIT_SEND_DEMO`.

## Complete Integration

#### index.html

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>RCS Message Demo</title>
</head>
<body>
  <iframe
    id="send_rcs"
    src="https://embed.pinnacle.sh/embed/v2/send-rcs-message"
    style="width: 100vw; height: 100vh; border: none;">
  </iframe>

  <script>
    const iframe = document.getElementById('send_rcs');

    window.addEventListener('message', async (event) => {
      if (event.origin !== 'https://embed.pinnacle.sh') return;

      if (event.data.type === 'RCS_WIDGET_READY') {
        // Fetch token from your backend
        const res = await fetch('/api/get-send-rcs-message-token');
        const { signedToken } = await res.json();

        // Initialize the widget
        iframe.contentWindow.postMessage({
          type: 'INIT_SEND_DEMO',             // required
          signedToken: signedToken,           // required
          primaryColor: '#16a34a'
        }, 'https://embed.pinnacle.sh');
      }
    });
  </script>
</body>
</html>
```

#### server.ts

```typescript
import 'dotenv/config';
import express from 'express';
import path from 'path';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const app = express();
app.use(express.json());
app.use(express.static('public'));

app.get('/', (req, res) => {
  res.sendFile(path.join(__dirname, 'index.html'));
});

app.get('/api/get-send-rcs-message-token', async (req, res) => {
  const response = await fetch('https://api.pinnacle.sh/embed/get-token', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'pinnacle-api-key': process.env.PINNACLE_API_KEY!
    },
    body: JSON.stringify({
      // required
      agentId: process.env.AGENT_ID!,
      scopes: ['MESSAGES.SEND'],
      configuredMessage: {
        // required
        agentName: "Your Brand",
        agentIconUrl: "https://example.com/icon.png",
        title: "Message Title",
        subtitle: "Message Subtitle",
        basicText: "Your message content",
        consentText: "Message and data rates may apply.",
        termsUrl: "https://example.com/terms",
        privacyUrl: "https://example.com/privacy",

        // optional
        imageUrl: "https://example.com/image.jpg",
        videoUrl: "https://example.com/video.mp4",
        pdfUrl: "https://example.com/document.pdf",
        pdfSize: 10,
        quickReplies: [
          { type: 'trigger', title: 'Shop Now', payload: 'shop_action' },
          { type: 'openUrl', title: 'Learn More', payload: 'https://example.com' },
          { type: 'call', title: 'Call Support', payload: '+14155551234' },
          {
            type: 'sendLocation',
            title: 'Get Directions',
            latLong: { lat: 37.7749, lng: -122.4194 },
            name: 'Store Location'
          },
          { type: 'requestUserLocation', title: 'Find Nearby' },
          {
            type: 'scheduleEvent',
            title: 'Add to Calendar',
            eventStartTime: '2025-02-21T10:00:00Z',
            eventEndTime: '2025-02-21T11:00:00Z',
            eventTitle: 'Product Demo',
          }
        ]
      }
    })
  });

  const { signedToken } = await response.json();
  res.json({ signedToken });
});

app.listen(8080, () => {
  console.log('Server running at http://localhost:8080');
});
```

#### package.json

```json
{
  "name": "rcs-embed-demo",
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "dev": "tsx watch server.ts",
    "start": "tsx server.ts"
  },
  "dependencies": {
    "dotenv": "^16.4.7",
    "express": "^5.2.1"
  },
  "devDependencies": {
    "@types/express": "^5.0.6",
    "@types/node": "^20",
    "tsx": "^4.19.3",
    "typescript": "^5"
  }
}
```

#### .env.example

```bash
# https://app.pinnacle.sh/dashboard/development/api-keys
PINNACLE_API_KEY=pnclk_your_api_key_here

# https://app.pinnacle.sh/dashboard/agents
AGENT_ID=agent_XXXXXXXXXXXX
```