> ## Documentation Index
> Fetch the complete documentation index at: https://messages.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Typing Indicators

> Send and receive typing indicators

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

<CodeGroup>
  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
  import { createClient } from "@messages-dev/sdk";

  const client = createClient();

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

  ```bash curl theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
  curl -X POST "https://api.messages.dev/v1/typing" \
    -H "Authorization: Bearer sk_live_..." \
    -H "Content-Type: application/json" \
    -d '{
      "from": "+15551234567",
      "to": "+15559876543"
    }'
  ```
</CodeGroup>

The indicator appears for a few seconds. To stop it before it expires naturally:

<CodeGroup>
  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
  await client.stopTyping({
    from: "+15551234567",
    to: "+15559876543",
  });
  ```

  ```bash curl theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
  curl -X POST "https://api.messages.dev/v1/typing" \
    -H "Authorization: Bearer sk_live_..." \
    -H "Content-Type: application/json" \
    -d '{
      "from": "+15551234567",
      "to": "+15559876543",
      "state": "off"
    }'
  ```
</CodeGroup>

## Common pattern: type while processing

Show a typing indicator while your bot generates a response, then send the message:

```typescript theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
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:

```typescript theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
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:

<CodeGroup>
  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
  const indicators = await client.listTypingIndicators({
    from: "+15551234567",
    to: "+15559876543",
  });

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

  ```bash curl theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
  curl "https://api.messages.dev/v1/typing?from=+15551234567&to=+15559876543" \
    -H "Authorization: Bearer sk_live_..."
  ```
</CodeGroup>
