> 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-typing/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.pinnacle.sh/_mcp/server.
# Send Typing Indicator RCS
POST https://api.pinnacle.sh/messages/send/typing
Content-Type: application/json
Send a typing indicator from an RCS agent to a recipient.
This endpoint allows RCS agents to display a typing indicator to recipients. The indicator is a message bubble with animated typing dots like this:
**Use Case:** Typing indicators are especially useful for providing feedback to users while the agent is thinking or generating a response that may take some time, creating a more engaging conversational experience.
**Expiration:** Typing indicators automatically expire after around 20 seconds or when the agent sends a message, whichever comes first.
**Frequency:** You can send typing indicators as many times as needed, though only one will be displayed at a time. Sending multiple typing indicators will extend the duration of the current indicator.
> **Note:** Typing indicators are best-effort hints, not delivery-guaranteed state. The platform is allowed to coalesce or drop them, and the client UI decides when to show/hide.
Reference: https://docs.pinnacle.sh/api-reference/messages/send-typing
## Authentication
- `PINNACLE-API-KEY` header (required) — API Key authentication via header
## Request
### Body (application/json)
This endpoint expects a SendTypingIndicatorSchema.
- `agentId` (string, required) — The unique identifier of the RCS agent sending the typing indicator. Format: `agent_` followed by alphanumeric characters (e.g., `agent_pinnacle`).
- `to` (string, required) — The recipient's phone number in E.164 format. Must include country code with a leading plus sign (e.g., `+14155551234`).
## Response
### 200
Successfully sent the typing indicator.
- `success` (boolean, required) — Indicates whether the typing indicator was successfully sent.
- `agentId` (string, required) — The RCS agent that sent the typing indicator.
- `recipient` (string, required) — The recipient's phone number that received the typing indicator.
- `startedAt` (string, required) — Timestamp when the typing indicator was started (ISO 8601 format).
- `endedAt` (string, required) — Timestamp when the typing indicator will automatically expire (ISO 8601 format). This is typically one minute after `startedAt` unless a message is sent first.
## 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.
- `SendTypingIndicatorRequestBadRequestError`
### 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.
### 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
### 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.
### 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
**Request**
```json
{
"agentId": "agent_pinnacle",
"to": "+14154746461"
}
```
**Response**
```json
{
"success": true,
"agentId": "agent_pinnacle",
"recipient": "+14154746461",
"startedAt": "2025-11-10T14:30:00.000Z",
"endedAt": "2025-11-10T14:31:00.000Z"
}
```
**SDK Code**
```python Typing Indicator
import requests
url = "https://api.pinnacle.sh/messages/send/typing"
payload = {
"agentId": "agent_pinnacle",
"to": "+14154746461"
}
headers = {
"PINNACLE-API-KEY": "",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())
```
```javascript Typing Indicator
const url = 'https://api.pinnacle.sh/messages/send/typing';
const options = {
method: 'POST',
headers: {'PINNACLE-API-KEY': '', 'Content-Type': 'application/json'},
body: '{"agentId":"agent_pinnacle","to":"+14154746461"}'
};
try {
const response = await fetch(url, options);
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
```
```go Typing Indicator
package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.pinnacle.sh/messages/send/typing"
payload := strings.NewReader("{\n \"agentId\": \"agent_pinnacle\",\n \"to\": \"+14154746461\"\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 Typing Indicator
require 'uri'
require 'net/http'
url = URI("https://api.pinnacle.sh/messages/send/typing")
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 \"agentId\": \"agent_pinnacle\",\n \"to\": \"+14154746461\"\n}"
response = http.request(request)
puts response.read_body
```
```java Typing Indicator
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
HttpResponse response = Unirest.post("https://api.pinnacle.sh/messages/send/typing")
.header("PINNACLE-API-KEY", "")
.header("Content-Type", "application/json")
.body("{\n \"agentId\": \"agent_pinnacle\",\n \"to\": \"+14154746461\"\n}")
.asString();
```
```php Typing Indicator
request('POST', 'https://api.pinnacle.sh/messages/send/typing', [
'body' => '{
"agentId": "agent_pinnacle",
"to": "+14154746461"
}',
'headers' => [
'Content-Type' => 'application/json',
'PINNACLE-API-KEY' => '',
],
]);
echo $response->getBody();
```
```csharp Typing Indicator
using RestSharp;
var client = new RestClient("https://api.pinnacle.sh/messages/send/typing");
var request = new RestRequest(Method.POST);
request.AddHeader("PINNACLE-API-KEY", "");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n \"agentId\": \"agent_pinnacle\",\n \"to\": \"+14154746461\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```
```swift Typing Indicator
import Foundation
let headers = [
"PINNACLE-API-KEY": "",
"Content-Type": "application/json"
]
let parameters = [
"agentId": "agent_pinnacle",
"to": "+14154746461"
] as [String : Any]
let postData = JSONSerialization.data(withJSONObject: parameters, options: [])
let request = NSMutableURLRequest(url: NSURL(string: "https://api.pinnacle.sh/messages/send/typing")! 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.