Skip to main content
The message history API is a beta. A team owner or admin must enroll the team on the Numbers page. Until the team is enrolled and the beta is offered to it, every history request returns 403 permission_denied.
The message history API returns conversations and messages that Polymorfa stored for a Number with hosted message storage enabled. Use it to backfill an inbox, render a conversation after a page reload, or reconcile your own store with what Polymorfa retained.

Before you start

  • Hosted message storage is on for the Number. History contains only messages received or sent after storage was enabled. For any other Number, history requests return 404 hms_not_enabled. Test numbers never have stored history.
  • Your team is enrolled in the beta. Enrollment is on the Numbers page of the Console. Withdrawing blocks new history reads and does not delete stored messages.
  • You call from your server with an organization key or project token. Client tokens are rejected with 403 permission_denied.
messages:read is a new scope. Credentials created before it existed, including full-access credentials, do not include it. Create a credential that lists messages:read explicitly.

List conversations

Conversations are ordered by most recent activity, newest first. Each entry carries the conversation identity, its kind, and a summary of the latest stored message. The summary has no message body; read messages for content.
A conversation appears only while at least one of its messages is retained. A conversation that receives a new message while you page moves to the top of the list; it is not repeated on later pages.

List messages in a conversation

Select the conversation by its id or by an E.164 phone number (URL-encode the + as %2B). Messages are newest first by default.
whatsapp_ids object holds the provider references that Polymorfa observed for the message. It contains linked_devices, official_api, or both. Use the Polymorfa id to fetch a message or send a reply. The older whatsapp_id field remains temporarily for integrations that still read one reference. In a group, an inbound message includes conversation.sender, the author. The message fields match message.received: text, caption, mimeType, filename, ptt, latitude, longitude, displayName, title, reaction, reactionTo, edited, unavailable, unavailableReason, and pollOptions appear when the stored message has them. Messages sent through the API are stored with their type and identifiers; their body is not part of the stored record.

Paginate

Cursors are opaque. Pass them back unchanged, with the same path and filters. A cursor used with different filters or a different conversation returns 400 invalid_parameter with param: "cursor"; start again without a cursor.
  • nextCursor continues in the current order. It is null on the last page, and hasMore is false.
  • previousCursor returns the page before the current one. It is null on the first page. Conversation lists do not have a previous cursor.

Media

History never returns WhatsApp media keys, download paths, or storage URLs. An image, video, audio, document, or sticker message has a media array. Download Linked Devices media entries with Download linked media using a credential with media:read. Download a stored Official API message’s media with Download stored message media using both messages:read and media:read. A stored-media ID is not a linked-media ID. The array is empty when Polymorfa has no downloadable copy of that file.

Official API media

WhatsApp keeps media from an Official API message for a limited time. When hosted message storage retains such a message, Polymorfa copies its media into the Number’s data region. The message then has a mediaRetrieval object. This applies to Numbers connected through the Official API only; on a Number that uses Hybrid Link, Official API media is not copied.
Every state except pending is final. A final state other than stored has a reason, for example provider_media_not_found or media_too_large; media is then empty. Polymorfa stores files up to 32 MiB, and never more than WhatsApp’s own limit for the media type: 5 MB for images, 500 KB for stickers, and 16 MB for audio and video. WhatsApp makes a file available for 7 days after it delivers the message, so a copy that is not stored within that time ends as expired. Download the copy with Download stored message media using a credential with both messages:read and media:read. The response body is the file itself, served as an attachment with its stored content type. The copy is deleted with the message when its retention period ends.

Retention and data region

History returns only messages inside the Number’s hosted storage retention period, or under legal hold. Expired messages are not returned, and a message can disappear between two pages when its retention period ends. Every successful response has a Polymorfa-Data-Region header naming the region that stored and served the history. History is read only in the Number’s region.

Errors

See Errors for the full error format.