Skip to main content

Read Receipts & Typing Indicators

Two lightweight sender actions let your integration behave like a person on the other end of the chat:

  • Read receipt: show the contact that their message was read (for example blue ticks on WhatsApp, "Seen" on Messenger and Instagram).
  • Typing indicator: show "typing…" while your bot or backend prepares a reply.

Sender actions are not messages:

  • They are not billed and do not count towards your message pool.
  • No message is created in the conversation.
  • No webhook is sent.
  • Your inbox's own unread state is not changed. Marking a message as read for the contact does not mark the conversation as read for your team.

Required Scopes​

ScopePurpose
messages:createSend read receipts and typing indicators
channels:readCheck which channels support them

Channel Support​

ChannelRead receiptTyping indicatorCan be cleared (off)Typing lasts
WhatsAppYesYes (also marks as read)NoUp to 25 s or until you reply
MessengerYesYesYesAbout 20 s
InstagramYesYesYesAbout 20 s
TelegramNoYesNoAbout 5 s
RCSYesYesNoAbout 20 s or until you reply
Live ChatNoYesYesUntil cleared or until you reply
SMSNoNoNo—
EmailNoNoNo—
Browser PushNoNoNo—
ViberNoNoNo—

Messenger and Instagram only accept sender actions inside the standard 24-hour messaging window.

Always check support at runtime instead of hard-coding this table:

GET /api/v1/channels/sender-actions
curl "https://api.sendseven.com/api/v1/channels/sender-actions" \
-H "Authorization: Bearer s7_api_a1b2c3d4e5f6789012345678abcdef00"
{
"items": [
{
"channel_type": "whatsapp",
"read": true,
"typing": true,
"typing_off": false,
"typing_ttl_seconds": 25,
"typing_requires_message": true
},
{
"channel_type": "telegram",
"read": false,
"typing": true,
"typing_off": false,
"typing_ttl_seconds": 5,
"typing_requires_message": false
}
],
"pagination": {
"total": 10,
"page": 1,
"page_size": 10,
"total_pages": 1,
"has_next": false,
"has_prev": false
}
}

Every channel type is listed; unsupported ones report false. The same object (without channel_type) is returned as sender_actions on GET /channels/{channel_id}/capabilities.

FieldMeaning
readRead receipts are supported
typingTyping indicators are supported
typing_offThe indicator can be cleared with state: "off". When false, off is accepted but does nothing; the indicator ends on its own
typing_ttl_secondsHow long one typing call stays visible. null = until cleared or until you reply
typing_requires_messageThe platform ties typing to a received message. SendSeven uses the latest inbound message if you don't pass message_id

Mark a Message as Read​

POST /api/v1/messages/{message_id}/read

No request body is needed. Only inbound messages (sent by the contact) can be marked as read.

curl -X POST "https://api.sendseven.com/api/v1/messages/f47ac10b-58cc-4372-a567-0e02b2c3d479/read" \
-H "Authorization: Bearer s7_api_a1b2c3d4e5f6789012345678abcdef00"
{
"success": true,
"action": "read",
"state": null,
"message_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"conversation_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"channel_type": "whatsapp",
"expires_in_seconds": null,
"implied_read": false,
"deduplicated": false
}

Show or Clear a Typing Indicator​

POST /api/v1/conversations/{conversation_id}/typing

Request Body (optional)​

FieldTypeRequiredDescription
statestringNoon (default) or off
message_idstringNoAn inbound message of this conversation to attach the indicator to. Only used where typing_requires_message is true; defaults to the latest inbound message

An empty body is the same as {"state": "on"}.

curl -X POST "https://api.sendseven.com/api/v1/conversations/7c9e6679-7425-40de-944b-e07fc1f90ae7/typing" \
-H "Authorization: Bearer s7_api_a1b2c3d4e5f6789012345678abcdef00" \
-H "Content-Type: application/json" \
-d '{"state": "on"}'
{
"success": true,
"action": "typing",
"state": "on",
"message_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"conversation_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"channel_type": "whatsapp",
"expires_in_seconds": 25,
"implied_read": true,
"deduplicated": false
}
  • expires_in_seconds: when the platform will hide the indicator on its own. Call again before then to keep it visible during a long operation (for example every 4 seconds on Telegram, every 20 seconds on WhatsApp).
  • implied_read: true when the indicator also marked the message as read. On WhatsApp a typing indicator always marks the contact's message as read — don't use it if you don't want the contact to see read ticks.
  • Sending your reply ends the indicator on every channel; you don't need to send off first.

Repeated Calls & Limits​

You don't need to track what you already sent — SendSeven absorbs repeats:

  • Read receipts are sent once per message. Marking the same message as read again returns 200 with deduplicated: true and nothing is sent to the channel.
  • Typing on is deduplicated. Another on for the same conversation within half of the channel's typing duration (typing_ttl_seconds) returns 200 with deduplicated: true; the indicator is still showing. Refresh it at roughly half the duration to keep it visible continuously.
  • Typing off is never deduplicated or limited.
  • Rate limit: about 30 read/typing calls per minute per conversation reach the channel. Above that you get 429 sender_action_rate_limited with a Retry-After header (seconds).

deduplicated is false whenever the action was actually sent.

Errors​

Errors use a structured detail object:

{
"detail": {
"code": "sender_action_not_supported",
"message": "Read receipts are not supported on this channel.",
"channel_type": "telegram",
"action": "read"
}
}
HTTPcodeWhen
404message_not_foundThe message doesn't exist, isn't visible to you, or (typing) isn't in this conversation
404conversation_not_foundThe conversation doesn't exist or isn't visible to you
422sender_action_not_supportedThe channel doesn't support this action (see the table above)
422message_not_inboundYou tried to mark one of your own outbound messages as read
422no_inbound_messageTyping on a channel that needs a received message, but the conversation has none
422channel_unavailableThe channel is disconnected or can't be used right now
429sender_action_rate_limitedMore than about 30 calls per minute for this conversation. Wait for Retry-After seconds
502sender_action_failedThe messaging platform rejected the request (for example outside the 24-hour window on Messenger)

For 502 sender_action_failed, message is a generic, safe description. When the cause is known it may include a short hint (for example that the messaging window has closed). The platform's raw error is never passed through, so don't parse message — branch on code.

Sender actions are best-effort UX signals: treat a failure as non-fatal and send your reply anyway.