# Receiving WhatsApp text messages

A contact who types into the chat produces an inbound message carrying `text`. It is the most common inbound arm, and the one that opens or resets the [customer service window](/docs/knowledge-base/whatsapp/customer-service-window).

## What an inbound text carries

`text.body` holds what the contact typed, and nothing else sits on the arm:

```json
{
  "id": "wam_01kya19eknftrs2s6p82asmvnh",
  "direction": "inbound",
  "from": { "phone_number": "+14155550100", "display_name": "Alex Rivera" },
  "to": { "phone_number": "+13124495569" },
  "status": "received",
  "text": { "body": "Is my order out for delivery yet?" },
  "created_at": "2026-08-25T09:04:11Z"
}
```

`preview_url` is a send-side field. An inbound text carries no flag for a link preview, whatever the contact's own client rendered, so a URL in `body` reads back as part of the text.

The read schema declares no maximum on an inbound `body`. The 4096-character cap belongs to the [send side](/docs/guides/whatsapp/message-types/plain-text#limits), so size your storage as unbounded text rather than to a limit the inbound arm does not promise.

## A text sent as a quoted reply

When the contact replies to one of your messages by quoting it, the arm is unchanged and `in_reply_to_message_id` names the message they answered:

```json
{
  "id": "wam_01kyb2m4xq7whs0d8n3prv6tez",
  "direction": "inbound",
  "from": { "phone_number": "+14155550100" },
  "to": { "phone_number": "+13124495569" },
  "status": "received",
  "in_reply_to_message_id": "wam_01kya19eknftrs2s6p82asmvnh",
  "text": { "body": "Yes, that one" },
  "created_at": "2026-08-25T09:06:02Z"
}
```

WhatsApp does not mark every reply, and an unmarked one carries no ID at all. See [quoted replies](/docs/guides/whatsapp/receiving-whatsapp#quoted-replies) on the hub for what resolution can miss and how to correlate without it.

## The webhook payload

`whatsapp.received` carries the same arm on the event envelope, so an endpoint acts on the text without reading the message back:

```json
{
  "type": "whatsapp.received",
  "timestamp": "2026-08-25T09:04:11.118Z",
  "data": {
    "whatsapp_id": "wam_01kya19eknftrs2s6p82asmvnh",
    "workspace_id": "ws_01ky7m235keycbnwyajabe1a6b",
    "direction": "inbound",
    "from": { "phone_number": "+14155550100", "display_name": "Alex Rivera" },
    "to": { "phone_number": "+13124495569" },
    "text": { "body": "Is my order out for delivery yet?" },
    "tags": null,
    "metadata": null
  }
}
```

## Things to watch

- **A text is the cheapest way a contact reopens the window.** Any inbound message resets the service window to 24 hours, and a text is what most contacts send; a free-form reply of your own is deliverable from that moment.
- **`from` can arrive without a phone number.** A contact who has adopted a WhatsApp username reaches you by [business-scoped user ID](/docs/guides/whatsapp/business-scoped-user-ids), so read the identity off `from` rather than assuming `from.phone_number` is set.
- **The body is the contact's own typing.** A tap on something you sent arrives as an [interactive reply](/docs/guides/whatsapp/receiving-whatsapp/interactive-replies) on its own arm instead.

## Next steps

- [How receiving works](/docs/guides/whatsapp/receiving-whatsapp): the inbound envelope, media fetching, and the `whatsapp.received` webhook
- [WhatsApp plain text messages](/docs/guides/whatsapp/message-types/plain-text): the send side of the same arm
- [Receiving interactive replies](/docs/guides/whatsapp/receiving-whatsapp/interactive-replies): what a tap on a button or a list row arrives as
- [Sending WhatsApp messages](/docs/guides/whatsapp/sending-whatsapp): replying inside the service window, and quoting a message