Skip to main content
Typing indicators show the ”…” bubble in the recipient’s iMessage conversation. You can send them to signal that your bot or integration is composing a response, and receive them via webhooks when someone is typing to you.

Send a typing indicator

import { createClient } from "@messages-dev/sdk";

const client = createClient();

await client.startTyping({
  from: "+15551234567",
  to: "+15559876543",
});
The indicator appears for a few seconds. To stop it before it expires naturally:
await client.stopTyping({
  from: "+15551234567",
  to: "+15559876543",
});

Common pattern: type while processing

Show a typing indicator while your bot generates a response, then send the message:
const client = createClient();

await client.startTyping({
  from: "+15551234567",
  to: "+15559876543",
});

const reply = await generateReply(incomingMessage);

await client.sendMessage({
  from: "+15551234567",
  to: "+15559876543",
  text: reply,
});

Receive typing indicators via webhooks

Subscribe to typing.started and typing.stopped events:
import { verifyWebhook } from "@messages-dev/sdk";

app.post("/webhooks", async (req, res) => {
  const event = await verifyWebhook(
    req.body,
    req.headers["x-webhook-signature"],
    "your_webhook_secret",
  );

  if (event.event === "typing.started") {
    console.log(`${event.data.handle} is typing...`);
  }

  if (event.event === "typing.stopped") {
    console.log(`${event.data.handle} stopped typing`);
  }

  res.sendStatus(200);
});

Get current typing status

Check who is currently typing in a chat:
const indicators = await client.listTypingIndicators({
  from: "+15551234567",
  to: "+15559876543",
});

for (const ind of indicators.data) {
  if (ind.isTyping) {
    console.log(`${ind.handle} is typing`);
  }
}