List messages in a chat

GEThttps://api.wapito.com/v1/messages/list/{chat_id}

Send a channel token on every request: Authorization: Bearer wpt_YOUR_TOKEN

Beta

Returns a page of messages from one chat, newest first, with filters for direction and time window. History comes from the engine store, so a channel only sees messages received or sent since it connected, and only when engine storage is enabled. Treat this as a convenience for recent context, not as an archive: keep your own copy of anything you need permanently.

Parameters

NameInTypeRequiredDescriptionExample
chat_idpathstringRequiredChat to read, in any accepted recipient form.15551234567@s.whatsapp.net
countqueryintegerOptionalPage size, 1-500. Defaults to 100.1–500 · default 10050
offsetqueryintegerOptionalItems to skip before the first returned item. Use it with `count` to page.min 0 · default 00
from_mequerybooleanOptionalReturn only outbound (`true`) or only inbound (`false`) messages.true
time_fromqueryintegerOptionalOnly messages at or after this Unix epoch millisecond timestamp.1789372800000
time_toqueryintegerOptionalOnly messages at or before this Unix epoch millisecond timestamp.1789459200000

Responses

200

A page of messages.

Fields of the 200 response
FieldTypeRequiredDescription
countintegerRequiredNumber of items in this page.
messagesarray of objectRequiredPage of results.
audioobjectOptionalMedia attached to a message. `link` is a signed Wapito URL, not a WhatsApp CDN URL.
captionstring | nullRequiredCaption sent alongside the media.
errorstringOptionalSet to `unavailable` when the media could not be copied before it expired on the engine.one of unavailable
file_namestring | nullRequiredOriginal file name when the sender supplied one.
file_sizeinteger | nullRequiredSize in bytes.
idstring | nullRequiredWapito media id (`med_` + ULID), or `null` when the copy from the engine failed.
linkstring | nullRequiredSigned `/v1/media/{id}?exp&sig` URL, valid 24 h on sandbox and 7 days on premium.
mime_typestringRequiredIANA media type reported by WhatsApp.
chat_idstringRequiredChat the message belongs to, as `@s.whatsapp.net`, `@g.us` or `@newsletter`.
contactobjectOptionalContact card payload of a `contact` message.
vcardstringRequiredRaw vCard 3.0 text as WhatsApp stores it.
contextobjectOptionalReply, forward and mention context for a message.
forwardedbooleanRequiredWhether WhatsApp marked the message as forwarded.
mentionsarray of stringRequiredPhone numbers mentioned with @ in the body.
quoted_authorstring | nullRequiredSender of the quoted message.
quoted_idstring | nullRequiredId of the quoted message, when this message is a reply.
documentobjectOptionalMedia attached to a message. `link` is a signed Wapito URL, not a WhatsApp CDN URL.
captionstring | nullRequiredCaption sent alongside the media.
errorstringOptionalSet to `unavailable` when the media could not be copied before it expired on the engine.one of unavailable
file_namestring | nullRequiredOriginal file name when the sender supplied one.
file_sizeinteger | nullRequiredSize in bytes.
idstring | nullRequiredWapito media id (`med_` + ULID), or `null` when the copy from the engine failed.
linkstring | nullRequiredSigned `/v1/media/{id}?exp&sig` URL, valid 24 h on sandbox and 7 days on premium.
mime_typestringRequiredIANA media type reported by WhatsApp.
fromstring | nullRequiredSender in digits for direct chats, or the group id for group chats. `null` when only a LID is known.
from_lidstring | nullRequiredSender LID when WhatsApp addressed the message by LID rather than phone number.
from_mebooleanRequiredTrue when the channel sent the message, false when it received it.
from_namestring | nullRequiredPush name of the sender as WhatsApp reports it.
idstringRequiredEngine message id, unique within the channel.
imageobjectOptionalMedia attached to a message. `link` is a signed Wapito URL, not a WhatsApp CDN URL.
captionstring | nullRequiredCaption sent alongside the media.
errorstringOptionalSet to `unavailable` when the media could not be copied before it expired on the engine.one of unavailable
file_namestring | nullRequiredOriginal file name when the sender supplied one.
file_sizeinteger | nullRequiredSize in bytes.
idstring | nullRequiredWapito media id (`med_` + ULID), or `null` when the copy from the engine failed.
linkstring | nullRequiredSigned `/v1/media/{id}?exp&sig` URL, valid 24 h on sandbox and 7 days on premium.
mime_typestringRequiredIANA media type reported by WhatsApp.
locationobjectOptionalLocation payload of a `location` message.
addressstring | nullRequiredStreet address shown under the place name.
latitudenumberRequiredDecimal degrees.
longitudenumberRequiredDecimal degrees.
namestring | nullRequiredPlace name shown in the bubble.
participantstring | nullRequiredIn group chats, the individual sender behind `from`.
pollobjectOptionalPoll payload of a `poll` message. Votes arrive later as `polls` webhook events.
multiplebooleanRequiredWhether voters may select more than one option.
optionsarray of stringRequiredAnswer options in display order.
titlestringRequiredPoll question.
rawobjectOptionalUntouched engine payload. Present only while `settings.include_raw` is enabled.
sourcestringRequired`app` when the message came from the linked phone, `api` when Wapito sent it.one of app, api
statusstringOptionalDelivery state of an outbound message.one of failed, pending, sent, delivered, read, played
stickerobjectOptionalMedia attached to a message. `link` is a signed Wapito URL, not a WhatsApp CDN URL.
captionstring | nullRequiredCaption sent alongside the media.
errorstringOptionalSet to `unavailable` when the media could not be copied before it expired on the engine.one of unavailable
file_namestring | nullRequiredOriginal file name when the sender supplied one.
file_sizeinteger | nullRequiredSize in bytes.
idstring | nullRequiredWapito media id (`med_` + ULID), or `null` when the copy from the engine failed.
linkstring | nullRequiredSigned `/v1/media/{id}?exp&sig` URL, valid 24 h on sandbox and 7 days on premium.
mime_typestringRequiredIANA media type reported by WhatsApp.
textobjectOptionalBody of a `text` message.
bodystringRequiredMessage text, WhatsApp markdown allowed.
timestampintegerRequiredUnix epoch milliseconds.
typestringRequiredMessage kind; selects which payload field is populated.one of text, image, video, audio, voice, document, sticker, location, contact, poll, reaction, unknown
videoobjectOptionalMedia attached to a message. `link` is a signed Wapito URL, not a WhatsApp CDN URL.
captionstring | nullRequiredCaption sent alongside the media.
errorstringOptionalSet to `unavailable` when the media could not be copied before it expired on the engine.one of unavailable
file_namestring | nullRequiredOriginal file name when the sender supplied one.
file_sizeinteger | nullRequiredSize in bytes.
idstring | nullRequiredWapito media id (`med_` + ULID), or `null` when the copy from the engine failed.
linkstring | nullRequiredSigned `/v1/media/{id}?exp&sig` URL, valid 24 h on sandbox and 7 days on premium.
mime_typestringRequiredIANA media type reported by WhatsApp.
voiceobjectOptionalMedia attached to a message. `link` is a signed Wapito URL, not a WhatsApp CDN URL.
captionstring | nullRequiredCaption sent alongside the media.
errorstringOptionalSet to `unavailable` when the media could not be copied before it expired on the engine.one of unavailable
file_namestring | nullRequiredOriginal file name when the sender supplied one.
file_sizeinteger | nullRequiredSize in bytes.
idstring | nullRequiredWapito media id (`med_` + ULID), or `null` when the copy from the engine failed.
linkstring | nullRequiredSigned `/v1/media/{id}?exp&sig` URL, valid 24 h on sandbox and 7 days on premium.
mime_typestringRequiredIANA media type reported by WhatsApp.
offsetintegerRequiredOffset this page started at.
totalinteger | nullRequiredTotal matches when the engine can count them, otherwise `null`.
{
  "count": 2,
  "messages": [
    {
      "chat_id": "15551234567@s.whatsapp.net",
      "context": {
        "forwarded": false,
        "mentions": [],
        "quoted_author": null,
        "quoted_id": null
      },
      "from": "15551234567",
      "from_lid": "187264518273645@lid",
      "from_me": false,
      "from_name": "Dana Whitfield",
      "id": "false_15551234567@s.whatsapp.net_9F31A0C4D7E2B6081A55",
      "image": {
        "caption": "Here is the receipt you asked for",
        "file_name": "receipt.jpg",
        "file_size": 184213,
        "id": "med_01JRQ8F4X9N2K7YB3C5V6W8H0T",
        "link": "https://api.wapito.com/v1/media/med_01JRQ8F4X9N2K7YB3C5V6W8H0T?exp=1790064121&sig=8f2c1d94b6a70e35",
        "mime_type": "image/jpeg"
      },
      "participant": null,
      "source": "app",
      "status": "delivered",
      "timestamp": 1789459321000,
      "type": "image"
    },
    {
      "chat_id": "15551234567@s.whatsapp.net",
      "context": {
        "forwarded": false,
        "mentions": [],
        "quoted_author": null,
        "quoted_id": null
      },
      "from": "15557654321",
      "from_lid": null,
      "from_me": true,
      "from_name": "Acme Support",
      "id": "true_15551234567@s.whatsapp.net_3EB0C767D82B0A1E4F2B",
      "participant": null,
      "source": "api",
      "status": "sent",
      "text": {
        "body": "Your order #4182 has shipped. Track it here: https://acme.example/t/4182"
      },
      "timestamp": 1789459200000,
      "type": "text"
    }
  ],
  "offset": 0,
  "total": 184
}

400

The request body or query string is malformed, or the recipient cannot be parsed into a WhatsApp id.

Show 2 example bodies

invalid_recipient — `to` is not a dialable number or valid WhatsApp id

{
  "error": {
    "code": "invalid_recipient",
    "details": {
      "to": "+1555"
    },
    "message": "The recipient is not a valid WhatsApp address.",
    "request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
  }
}

invalid_request — schema validation failed

{
  "error": {
    "code": "invalid_request",
    "details": {
      "issues": [
        {
          "message": "Array must contain at least 2 element(s)",
          "path": "body.options"
        }
      ]
    },
    "message": "The request payload failed validation.",
    "request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
  }
}

401

The channel token is missing, malformed, revoked or belongs to a deleted channel.

Show 2 example bodies

token_revoked — the token was rotated in the dashboard

{
  "error": {
    "code": "token_revoked",
    "message": "This channel token has been revoked.",
    "request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
  }
}

unauthorized — no or unusable Bearer token

{
  "error": {
    "code": "unauthorized",
    "message": "Missing or invalid channel token.",
    "request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
  }
}

403

The token is valid but the channel may not perform this action right now.

Show 2 example bodies

channel_locked — billing lapsed or the channel was locked by an operator

{
  "error": {
    "code": "channel_locked",
    "details": {
      "reason": "plan_required"
    },
    "message": "This channel is locked.",
    "request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
  }
}

forbidden — the channel does not own the target object

{
  "error": {
    "code": "forbidden",
    "message": "You are not allowed to perform this action.",
    "request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
  }
}

404

The addressed object does not exist, or the number is not on WhatsApp.

Show 3 example bodies

message_not_found — the message id is unknown to the engine

{
  "error": {
    "code": "message_not_found",
    "message": "The requested message does not exist.",
    "request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
  }
}

not_found — unknown id

{
  "error": {
    "code": "not_found",
    "message": "The requested resource does not exist.",
    "request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
  }
}

not_on_whatsapp — the number is not registered

{
  "error": {
    "code": "not_on_whatsapp",
    "message": "This number is not registered on WhatsApp.",
    "request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
  }
}

409

The channel is in the wrong state for this action, or the account type does not support it.

Show 3 example bodies

business_account_required — labels need WhatsApp Business

{
  "error": {
    "code": "business_account_required",
    "message": "This action requires a WhatsApp Business account.",
    "request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
  }
}

channel_not_connected — link the number first

{
  "error": {
    "code": "channel_not_connected",
    "details": {
      "status": "qr"
    },
    "message": "The channel is not connected.",
    "request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
  }
}

channel_not_in_qr_state — no QR available while the session boots

{
  "error": {
    "code": "channel_not_in_qr_state",
    "details": {
      "status": "created"
    },
    "message": "The channel is not waiting for a QR scan.",
    "request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
  }
}

429

A rate limit, a plan quota or one of the anti-ban guards stopped the request. Every one of these is safe to retry later; read `Retry-After` when present.

Show 5 example bodies

cold_send_limit — too many first messages to new recipients this hour

{
  "error": {
    "code": "cold_send_limit",
    "details": {
      "resets_at": "2026-09-15T09:00:00.000Z",
      "window_cap": 20
    },
    "message": "The hourly limit for messages to new recipients is reached.",
    "request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
  }
}

quota_exceeded — plan quota for the day or month

{
  "error": {
    "code": "quota_exceeded",
    "details": {
      "quota": "sent",
      "resets_at": "2026-09-16T00:00:00.000Z",
      "used": 150
    },
    "message": "The plan quota for this resource is exhausted.",
    "request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
  }
}

rate_limited — per-minute API rate limit

{
  "error": {
    "code": "rate_limited",
    "details": {
      "retry_after": 12
    },
    "message": "Too many requests.",
    "request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
  }
}

send_rate_limited — the send queue did not drain within 20 s

{
  "error": {
    "code": "send_rate_limited",
    "details": {
      "retry_after": 5
    },
    "message": "The send queue for this channel is saturated.",
    "request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
  }
}

warmup_limit — the warm-up ladder cap for today

{
  "error": {
    "code": "warmup_limit",
    "details": {
      "cap": 200,
      "day": 2
    },
    "message": "The warm-up limit for this channel is reached.",
    "request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
  }
}

500

Something went wrong inside Wapito. Quote `request_id` when reporting it.

Show the example body

internal_error — unexpected failure

{
  "error": {
    "code": "internal_error",
    "message": "Something went wrong on our side.",
    "request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
  }
}

502

The engine answered with an error Wapito could not translate into a more specific code.

Show the example body

engine_error — unexpected engine failure

{
  "error": {
    "code": "engine_error",
    "details": {
      "engine": "gows",
      "status": 500
    },
    "message": "The WhatsApp engine returned an error.",
    "request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
  }
}

503

The engine session is not reachable. Retry with backoff.

Show the example body

engine_unavailable — engine down or restarting

{
  "error": {
    "code": "engine_unavailable",
    "details": {
      "engine": "gows"
    },
    "message": "The WhatsApp engine is unavailable.",
    "request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
  }
}

504

The engine did not answer before the upstream timeout.

Show the example body

engine_timeout — no answer within the deadline

{
  "error": {
    "code": "engine_timeout",
    "details": {
      "timeout_ms": 20000
    },
    "message": "The WhatsApp engine did not respond in time.",
    "request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
  }
}

Errors

Code examples

import requests

url = "https://api.wapito.com/v1/messages/list/15551234567@s.whatsapp.net"

querystring = {"count":"50","offset":"0","from_me":"true","time_from":"1789372800000","time_to":"1789459200000"}

headers = {"Authorization": "Bearer wpt_YOUR_TOKEN"}

response = requests.get(url, headers=headers, params=querystring)

print(response.json())

Related

Try it on your own number

Create a channel, link a WhatsApp number by QR or pairing code, and call the API in a couple of minutes. The Sandbox plan is free and needs no card.