--- title: Typing Indicators API | Sendblue Docs description: 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. ## Sending Typing Indicators Display a typing indicator to a recipient, showing them that a message is being composed. ``` POST https://api.sendblue.co/api/send-typing-indicator ``` ### Request Body | Parameter | Type | Required | Description | | ------------- | ------ | -------- | ----------------------------------------------------- | | `number` | string | Yes | The recipient’s phone number (E.164 format) | | `from_number` | string | No | Your Sendblue line number to send from (E.164 format) | ### Example Request Terminal window ``` curl -X POST 'https://api.sendblue.co/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" }' ``` ### Node.js Example ``` const axios = require('axios'); await axios.post( 'https://api.sendblue.co/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' } } ); ``` ### Python Example ``` import requests response = requests.post( 'https://api.sendblue.co/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' } ) ``` ### Success Response (200) ``` { "status": "QUEUED", "status_code": 200, "error_message": null, "number": "+14155551234" } ``` ### Error Responses #### Missing Number (400) ``` { "status": "ERROR", "message": "You must specify a `number` in the request body." } ``` #### No Route Mapping (400) ``` { "status": "ERROR", "status_code": 400, "error_message": "No route mapping found for number, have you messaged them before?", "number": "+14155551234" } ``` --- ## Receiving Typing Indicators Get notified in real-time when your contacts start or stop typing via webhooks. ### Configuring the Webhook Register a `typing_indicator` webhook to receive typing events: Terminal window ``` curl -X POST 'https://api.sendblue.co/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" }' ``` ### Webhook Payload 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" } ``` ### Payload Fields | Field | Type | Description | | ------------- | ------- | ----------------------------------------------------- | | `number` | string | The phone number of the person typing (E.164 format) | | `is_typing` | boolean | `true` when typing starts, `false` when typing stops | | `from_number` | string | Your Sendblue line number that received the indicator | | `timestamp` | string | ISO 8601 timestamp of when the event was received | ### Node.js Webhook Handler Example ``` 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); ``` ### Python Webhook Handler Example ``` 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 ``` --- ## Notes 1. **iMessage Only**: Typing indicators are only supported for iMessage conversations, not SMS. 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](/getting-started/webhooks/index.md) 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