typing.start
Show the typing bubble on a contact's phone, in a one-to-one conversation they have written into — fire-and-forget, about twelve seconds, never retried.
POST /v1/commands/typing.startShows the typing dots on the other person's phone — the bubble Messages draws
while somebody is writing — in a one-to-one conversation the contact has
written into. Takes no arguments: payload is {} or absent.
It is not a queued command. On an iMessage line the relay serves typing as a
route of its own, fire-and-forget — nothing is journaled or replayed — and the
platform settles the command itself from that route's answer. So the 202 is followed within the second by a command frame, type: "typing.start", messageId: null.
On a live line Idempotency-Key is ignored, as on group.create: the presence route takes no key, so a repeat under the same key is a second request. What coalesces repeats is time — a second signal to the same conversation within five seconds settles succeeded and posts nothing; one after that shows the dots again, which is harmless. In test the sandbox honours the key.
Target
Prop
Type
On an iMessage line, live or test, the conversation at target.conversationId
must be one the transport has named and confirmed is with that one person
— which it does when it reports the conversation, the first time the contact
writes into it. A group, a conversation the transport has never named, and one
it has named but not confirmed are each 422 validation_failed at
target.conversationId before anything is sent; the unconfirmed case carries
reason: conversation_not_confirmed. Send the person a text first.
What happens
The 202 says the signal was accepted. What the command frame then says:
succeededonce the transport took the signal — never a promise that the phone drew it.failed, with the code of what the transport answered instead:not_found,rate_limited(the relay's own cap on typing, twelve a minute per conversation) orupstream_unavailable(the Mac behind the line is offline). It is never retried.
The bubble shows for about twelve seconds, or until the line sends into the
conversation. There is no call that takes it down; to hold it up, send
typing.start again.
At most one signal per conversation per five seconds is sent. Another inside
that window is accepted and settles succeeded without being sent again — the
bubble the first one raised is still up. So a loop that signals every few
seconds while an answer is being written costs one relay call per five
seconds, whatever its cadence.
Typing the contact does is not carried: no frame, event or webhook says a person is typing. The signal only ever goes out.
In test
A test iMessage line accepts typing.start after the same refusals and
settles it succeeded, with nothing drawn: the sandbox phone shows no bubble,
and the five-second window is not rehearsed there.
Request
curl https://api.mapier.ai/v1/commands/typing.start \
-H "Authorization: Bearer $MAPIER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"target": {
"kind": "conversation",
"conversationId": "a0000000-0000-4000-8000-000000000001"
}
}'A common shape: signal once when the model starts, send the answer when it is ready. For an answer that takes longer than the bubble lasts, signal again every ten seconds or so until the send goes out.
Response
{ "commandId": "cmd-9", "status": "queued", "disposition": "queued" }Then, on the response stream:
{
"commandId": "cmd-9",
"logicalActionId": "…",
"status": "succeeded",
"errorCode": null,
"conversationId": "a0000000-0000-4000-8000-000000000001",
"type": "typing.start",
"messageId": null,
"failureClass": null
}Errors
A command answers the one set of HTTP refusals
POST /v1/commands/{type} publishes, so that table is
the one to handle. What is particular to this type:
422 validation_failedattarget.conversationIdfor a group, a conversation the transport has never named, or one it has not confirmed — the last withreason: conversation_not_confirmed.404 unsupported_commandwithreason: not_on_channelon a line whose channel does not carry it.
Settlement codes you will see for this command: not_found, rate_limited,
upstream_unavailable. See Error codes.