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

# POST /v1/messages/typing — Typing / Recording Indicator

> Show a live 'typing' or 'recording' indicator to a contact, without sending a message.

# Typing / Recording Indicator

```text theme={null}
POST https://pilotstatus.com.br/v1/messages/typing
```

Shows the contact a live **"typing" (digitando)** or **"recording" (gravando)** indicator **without sending a message**. The indicator auto-clears when a message is sent, or after a provider timeout (\~25s on Meta).

<Note>
  Typing is **also shown automatically** before every conversational send (on both Meta and Evolution numbers). Use this endpoint only to show the indicator independently of a send.
</Note>

## Headers

* `Content-Type: application/json`
* `x-api-key: ps_...` (or `x-api-key-id: <api_key_id>`) — a **number-scoped** key

## Body

<ParamField body="to" type="string" required>
  Destination phone in **E.164** or bare digits — the contact to show the indicator to.
</ParamField>

<ParamField body="state" default="typing" type="string">
  `typing` (default), `recording`, or `paused`.
</ParamField>

## Example

```bash theme={null}
curl -X POST "https://pilotstatus.com.br/v1/messages/typing" \
  -H "Content-Type: application/json" \
  -H "x-api-key: ps_your_key_here" \
  -d '{ "to": "5511999999999", "state": "typing" }'
```

## Response (200)

```json theme={null}
{ "ok": true, "sent": true, "provider": "META", "effectiveState": "typing" }
```

<ResponseField name="sent" type="boolean">
  `true` when the indicator was dispatched to the contact.
</ResponseField>

<ResponseField name="provider" type="string">
  `META` or `EVOLUTION`.
</ResponseField>

<ResponseField name="effectiveState" type="string">
  The indicator actually shown. Meta downgrades `recording` to `typing`.
</ResponseField>

<ResponseField name="note" type="string">
  Present when the indicator was adapted or could not be shown (e.g. a Meta conversation with no inbound message to attach to).
</ResponseField>

## Provider behavior

<Warning>
  **Meta Cloud API** has no standalone presence endpoint. Typing is emitted as a read receipt + typing indicator on the contact's **last inbound message**, so on Meta numbers:

  * it requires a **recent inbound message** to attach to (otherwise `sent:false`);
  * there is **no "recording" variant** — `recording` is shown as `typing`;
  * `paused` is a **no-op**.
</Warning>

**Evolution** (Pilot Status web / GO) numbers relay `composing` / `recording` / `paused` natively.

## Common errors

| Status | Meaning                                                                                       |
| ------ | --------------------------------------------------------------------------------------------- |
| `400`  | Invalid JSON, invalid `state`, or the key is not bound to a number (`code: NUMBER_NOT_FOUND`) |
| `401`  | Missing/invalid API key header (`x-api-key` / `x-api-key-id`)                                 |
| `403`  | A tenant-scoped key used on a number-scoped endpoint                                          |
| `404`  | No conversation with `to` (`code: CONVERSATION_NOT_FOUND`)                                    |
