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. Each entry names a file you can download with Download media using a credential with media:read. The array is empty when Polymorfa has no downloadable copy of that file.

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.