Skip to content
Get Started

Typing Indicators API

Send and receive iMessage typing indicators via the Sendblue API

Typing indicators (the ”…” bubble in iMessage) let recipients know when someone is composing a message. The Sendblue API supports both sending typing indicators to your contacts and receiving real-time notifications when your contacts are typing.

Display a typing indicator to a recipient, showing them that a message is being composed.

POST https://api.sendblue.com/api/send-typing-indicator
ParameterTypeRequiredDescription
numberstringYesThe recipient’s phone number (E.164 format)
from_numberstringNoYour Sendblue line number to send from (E.164 format)
statestringNo"start" (default) or "stop". Use "stop" to end an active typing indicator before its max_duration_ms expires (for example, when transferring to a human agent or canceling an AI reply).
max_duration_msintegerNoHow long (in milliseconds) the typing indicator should remain visible before automatically stopping. Defaults to 60000 (60 seconds). Must be between 1 and 300000 (5 minutes).
Terminal window
curl -X POST 'https://api.sendblue.com/api/send-typing-indicator' \
-H 'sb-api-key-id: YOUR_API_KEY' \
-H 'sb-api-secret-key: YOUR_API_SECRET' \
-H 'Content-Type: application/json' \
-d '{
"number": "+14155551234",
"from_number": "+19175551234"
}'

Showing a typing indicator for a specific duration

Section titled “Showing a typing indicator for a specific duration”

Useful for AI agents whose response time is variable — fire a longer indicator while the model thinks, then call state: "stop" as soon as the reply is ready.

Terminal window
curl -X POST 'https://api.sendblue.com/api/send-typing-indicator' \
-H 'sb-api-key-id: YOUR_API_KEY' \
-H 'sb-api-secret-key: YOUR_API_SECRET' \
-H 'Content-Type: application/json' \
-d '{
"number": "+14155551234",
"state": "start",
"max_duration_ms": 120000
}'
Terminal window
curl -X POST 'https://api.sendblue.com/api/send-typing-indicator' \
-H 'sb-api-key-id: YOUR_API_KEY' \
-H 'sb-api-secret-key: YOUR_API_SECRET' \
-H 'Content-Type: application/json' \
-d '{
"number": "+14155551234",
"state": "stop"
}'

Calling state: "stop" for a recipient who currently has no active indicator is a safe no-op.

const axios = require('axios');
await axios.post(
'https://api.sendblue.com/api/send-typing-indicator',
{
number: '+14155551234',
from_number: '+19175551234'
},
{
headers: {
'sb-api-key-id': 'YOUR_API_KEY',
'sb-api-secret-key': 'YOUR_API_SECRET',
'Content-Type': 'application/json'
}
}
);
import requests
response = requests.post(
'https://api.sendblue.com/api/send-typing-indicator',
json={
'number': '+14155551234',
'from_number': '+19175551234'
},
headers={
'sb-api-key-id': 'YOUR_API_KEY',
'sb-api-secret-key': 'YOUR_API_SECRET'
}
)
{
"status": "QUEUED",
"status_code": 200,
"error_message": null,
"number": "+14155551234"
}
{
"status": "ERROR",
"message": "You must specify a `number` in the request body."
}
{
"status": "ERROR",
"message": "`state` must be either \"start\" or \"stop\"."
}
{
"status": "ERROR",
"message": "`max_duration_ms` must be an integer between 1 and 300000."
}

Worker firmware does not yet support typing-v2 (503)

Section titled “Worker firmware does not yet support typing-v2 (503)”

Returned when the line’s underlying worker is on an older firmware that doesn’t honor state: "stop" or an explicit max_duration_ms. The fleet rolls out continuously — retry shortly. Legacy start requests with no duration are unaffected and always succeed.

{
"status": "ERROR",
"status_code": 503,
"error_message": "Worker firmware iowa-1.9.80 does not yet support typing-v2 state=\"stop\". Fleet update is rolling out; retry shortly.",
"number": "+14155551234"
}
{
"status": "ERROR",
"status_code": 400,
"error_message": "No route mapping found for number, have you messaged them before?",
"number": "+14155551234"
}

Get notified in real-time when your contacts start or stop typing via webhooks.

Register a typing_indicator webhook to receive typing events:

Terminal window
curl -X POST 'https://api.sendblue.com/api/account/webhooks' \
-H 'sb-api-key-id: YOUR_API_KEY' \
-H 'sb-api-secret-key: YOUR_API_SECRET' \
-H 'Content-Type: application/json' \
-d '{
"webhooks": ["https://your-server.com/webhooks/typing"],
"type": "typing_indicator"
}'

When a contact starts or stops typing, Sendblue will POST to your configured webhook:

{
"number": "+14155551234",
"is_typing": true,
"from_number": "+19175551234",
"timestamp": "2025-01-30T12:34:56.789Z"
}
FieldTypeDescription
numberstringThe phone number of the person typing (E.164 format)
is_typingbooleantrue when typing starts, false when typing stops
from_numberstringYour Sendblue line number that received the indicator
timestampstringISO 8601 timestamp of when the event was received
const express = require('express');
const app = express();
app.use(express.json());
app.post('/webhooks/typing', (req, res) => {
const { number, is_typing, from_number, timestamp } = req.body;
if (is_typing) {
console.log(`${number} started typing...`);
// Show typing indicator in your UI
} else {
console.log(`${number} stopped typing`);
// Hide typing indicator in your UI
}
res.status(200).send('OK');
});
app.listen(3000);
from flask import Flask, request
app = Flask(__name__)
@app.route('/webhooks/typing', methods=['POST'])
def handle_typing():
data = request.json
number = data.get('number')
is_typing = data.get('is_typing')
if is_typing:
print(f'{number} started typing...')
# Show typing indicator in your UI
else:
print(f'{number} stopped typing')
# Hide typing indicator in your UI
return 'OK', 200

  1. iMessage Only: Typing indicators are only supported for iMessage conversations, not SMS or RCS.

  2. Prior Conversation Required: To send a typing indicator, you must have an existing conversation with the recipient. The API uses the established route mapping to deliver the indicator.

  3. Real-time Events: Typing indicator webhooks are delivered in real-time as events occur on the device.

  4. Webhook Security: You can configure a secret for your typing indicator webhook to verify that requests are coming from Sendblue. See the Webhooks documentation for details.

  5. Best Practices:

    • Send a typing indicator before composing a response to create a more natural conversation flow
    • Use the is_typing boolean to toggle UI state in your application
    • Always respond with a 200-level status code to acknowledge receipt of webhook events

Plan availability: Auto typing indicator is available on the Free API plan and the AI Agent plan. You can enable it from the account settings page in your dashboard, or via the API endpoint below.

When auto typing indicator is enabled, Sendblue automatically sends a typing indicator on every inbound 1:1 iMessage your line receives. Useful for AI-agent and async-workflow setups: the sender sees the ”…” bubble immediately while your backend composes a real response.

The auto-trigger only runs when all of these are true:

  • The inbound is an iMessage (typing indicators don’t apply to SMS or RCS)
  • It’s a 1:1 conversation, not a group chat
  • It’s the first part of the inbound (multi-attachment messages don’t fire twice)

If any of those don’t hold, no auto typing indicator is sent and the inbound flows through normally.

POST https://api.sendblue.com/accounts/settings/auto-typing-indicator
ParameterTypeRequiredDescription
auto_typing_indicatorbooleanYestrue to enable, false to disable
Terminal window
curl -X POST 'https://api.sendblue.com/accounts/settings/auto-typing-indicator' \
-H 'sb-api-key-id: YOUR_API_KEY' \
-H 'sb-api-secret-key: YOUR_API_SECRET' \
-H 'Content-Type: application/json' \
-d '{
"auto_typing_indicator": true
}'
const axios = require('axios');
await axios.post(
'https://api.sendblue.com/accounts/settings/auto-typing-indicator',
{ auto_typing_indicator: true },
{
headers: {
'sb-api-key-id': 'YOUR_API_KEY',
'sb-api-secret-key': 'YOUR_API_SECRET',
'Content-Type': 'application/json'
}
}
);
import requests
response = requests.post(
'https://api.sendblue.com/accounts/settings/auto-typing-indicator',
json={'auto_typing_indicator': True},
headers={
'sb-api-key-id': 'YOUR_API_KEY',
'sb-api-secret-key': 'YOUR_API_SECRET'
}
)
{
"status": "OK",
"auto_typing_indicator": true
}
{
"status": "ERROR",
"message": "auto_typing_indicator must be a boolean"
}
  1. Setting takes effect on the next inbound. Cached account data invalidates immediately after the toggle write.
  2. Auto and manual coexist. Toggling auto on doesn’t disable the manual POST /api/send-typing-indicator endpoint — you can still send explicit indicators when you want (for example, before sending a follow-up message in the same conversation).
  3. Same delivery semantics as the manual endpoint: iMessage-only, requires an existing conversation with the recipient.