Skip to content

Typing indicator

The typing indicator shows the recipient that a message is being written.

Automatic indicator

Turbo Notify shows the typing indicator on its own for a short time before each send. Before that, the conversation is opened the way a person would: the number shows as online and the unread messages in that conversation are marked as read.

Use the endpoints below only when you need manual control over the typing indicator.

Start typing

To show that a message is being written, send a request with is_typing set to true.

typing.sh
curl -X POST \
https://api.turbonotify.com/v1/typing-indicator \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": {"number": "+5511988887777"},
"is_typing": true
}'

Turbo Notify responds with an asynchronous acceptance:

HTTP status: 202
{
  "operation_id": "op_typing_9f3c2a1d47e8",
  "status": {
    "state": "pending",
    "at": "2025-07-16T10:00:00Z"
  }
}

What happens when typing starts

Starting to type also opens the conversation, as in a WhatsApp used by a person, in this order:

  1. The number shows as online, if it was not already.
  2. The messages the number received in that conversation and has not read yet are marked as read (the “blue ticks” for whoever sent them).
  3. After a short random pause, between 0.3 and 1.5 seconds, “typing…” appears.

This way, “typing…” never shows up over unread messages. The number goes back offline on its own a few minutes after the last interaction with any conversation (this is the presence shown in WhatsApp: the number’s connection and status do not change).

All of this is automatic. It does not use message or contact quota and does not produce a webhook event. The plan required for the typing indicator stays the same: the read that comes with starting to type does not depend on the read feature of the Business plan or higher, which only applies to marking as read manually.

Stop typing

To stop the typing indicator manually, send the same request with is_typing set to false. Stopping only removes the indicator: no message is marked as read.

typing.sh
curl -X POST \
https://api.turbonotify.com/v1/typing-indicator \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": {"number": "+5511988887777"},
"is_typing": false
}'

Turbo Notify responds with an asynchronous acceptance:

HTTP status: 202
{
  "operation_id": "op_typing_5b8e0d6c21fa",
  "status": {
    "state": "pending",
    "at": "2025-07-16T10:00:05Z"
  }
}

Available recipients

The to field accepts exactly one of the three forms below, just like the send message route:

FormExampleWhen to use
number{"number": "+5511988887777"}A known E.164 number
group_id{"group_id": "grp_…"}A WhatsApp group
contact_id{"contact_id": "ct_…"}The contact’s ID in Turbo Notify (the phone number is looked up for you)

Typing indicator in groups

To show the typing indicator in a WhatsApp group, use to.group_id with the group’s identifier instead of to.number.

typing-group.sh
curl -X POST \
https://api.turbonotify.com/v1/numbers/NUMBER_ALIAS/typing-indicator \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": {"group_id": "grp_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4"},
"is_typing": true
}'

The group_id is the group’s identifier in the grp_{hex32} format, returned by the list groups endpoint.

Typing indicator by contact_id

Use to.contact_id to show typing to a contact in your Turbo Notify contacts without giving the phone number directly. The phone number is taken from the contact’s record.

typing-contact.sh
curl -X POST \
https://api.turbonotify.com/v1/numbers/NUMBER_ALIAS/typing-indicator \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": {"contact_id": "ct_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4"},
"is_typing": true
}'

Typing indicator from an extra number

In the nested form, the sender of the typing indicator is always the number in the path. To type from a registered, active extra number, use that form with the number’s alias in place of {ref}:

typing.sh
curl -X POST \
https://api.turbonotify.com/v1/numbers/vendas-sp/typing-indicator \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": {"number": "+5511988887777"},
"is_typing": true
}'

The two forms handle the sender differently:

  • Nested (POST /v1/numbers/{ref}/typing-indicator): the sender is always the number in the path. A from field in the body is ignored.
  • Flat (POST /v1/typing-indicator): always sends from the main number (main). A from field in the body does not cause a validation error, but it is silently dropped: the request returns 202 Accepted and the typing indicator comes from the main number, not from the number given in from.

To send a typing indicator from an extra number, you must use the nested form, with the extra number’s alias in the URL path. The flat form has no way to choose the sender, and because it reports no error, a from in the body gives the false impression that it worked.

If the alias in the path is not registered, or the number is not active, the request is rejected.

Learn more about extra numbers.

Webhook events

The typing indicator has no completion confirmation: the 202 Accepted only confirms the asynchronous acceptance, and no webhook event is delivered for these requests.

Possible errors

StatusError codeDescription
400contact_not_foundThe contact_id given in to does not belong to this organization.
400contacts_not_enabledSending by contact_id is unavailable right now. Try again later; if it persists, contact support.
400groups_not_enabledGroup features are unavailable right now. Try again later; if it persists, contact support.
400invalid_recipientThe recipient given in to could not be resolved to a sendable address. Giving none, or more than one, of number, group_id and contact_id returns 422 validation_error.
402feature_not_availableThe feature is not available on your plan.
401not_authenticatedThe API key is invalid or missing.
403insufficient_scopeThe API key does not have the messages:send scope (the response includes required_scope).
404number_not_foundThe {ref} in the path does not match any number on the account (on the flat route: the account has no main number yet).
400invalid_number_idThe value in the URL starts with num_ but is not a valid number id.
404group_not_foundThe group_id given in to was not found.
409number_not_connectedThe number is not connected to WhatsApp. Reconnect the number and try again.
422sender_not_foundThe alias or number given does not match any sender on the account.
422validation_errorThe request body is malformed or failed validation. The response includes details.errors with the list of invalid fields.
500internal_errorUnexpected internal server error.