curl --request POST \
--url https://api.wppfy.com/message/history-sync \
--header 'Content-Type: application/json' \
--header 'token: <api-key>' \
--data '
{
"number": "5511999999999@s.whatsapp.net",
"messageid": "3EB01234567890ABCDEF",
"count": 20
}
'{
"success": true,
"request_id": "5f0c2a8e-6d1b-4c3a-9e7f-1a2b3c4d5e6f",
"message": "History sync request sent. Messages will be received as history sync events.",
"details": {
"result_timeout_ms": 120000,
"requested_anchor_messageid": "3EB01234567890ABCDEF",
"anchor_messageid": "3EB01234567890ABCDEF",
"anchor_replaced": false
}
}Request on-demand history for a chat
Requests from WhatsApp an on-demand sync of older messages from a chat, going backward from a reference message (anchor).
To recover a saved message that failed to open (messageType: "error" in
/message/find), use POST /message/reload.
Rules:
- send
number countis optional and limited to 100messageidis optional; when provided, the API uses that message as the reference to fetch older messages from the chat
Note:
- Important: recovery may only happen after opening WhatsApp on the phone or keeping it active in the background
messageiddefines the reference message for loading earlier history; this field does not fetch that specific message- if you want to recover only a specific message
Xvia history, provide asmessageidthe message right afterXand usecount=1 - if
messageidis not provided, the API uses the oldest locally known message of that chat as the reference to fetch earlier history - messages are returned later via webhook/SSE in
historytype events and are also available in/message/find
Result
The response contains the request’s request_id. Messages arrive in the history webhook/SSE with event: "messages" and the request_id in each message. It also appears at the top of messages and chats batches when the entire batch belongs to the same request; mixed batches may omit it at the top. The request ends with a single event: "status" batch with the same request_id:
status:completedwhen WhatsApp confirms the request’s completion,timeoutwhen there was no conclusive response within 2 minutes,blockedwhen the phone indicates more messages but did not deliver a page that advancessuccessanderror: only when there is no possible next page;success: falseand the reason inerror(pagination_no_progress,anchor_unavailable,history_access_unavailableorcursor_lookup_failed). Always come withblockedhas_more: what the phone declared.truethere are more messages on the phone,falsethe beginning of the conversation was reached,nullnot confirmed. Some devices declaretruein every on-demand response, including empty ones: with them, pagination ends inblockedwithpagination_no_progress, never inhas_more: falsehistory_access:unavailablewhen there are more messages but WhatsApp does not grant access to themnext_request: ready-made body to request the earlier messages; resend it as received.nullwhen there is no usable next request
To paginate, resend next_request from the final result until it comes back null, waiting for the result of each request. completed ends the request, not the whole conversation. next_request: null without has_more: false does not prove the beginning of the conversation. Silence or a batch with fewer messages than count does not indicate the end of the history: only has_more: false does.
With blocked and error: "pagination_no_progress", stop paginating that chat without automatically repeating the request: it is the end of what the phone delivers from that anchor, and repeating gives the same result.
Each chat has one active request at a time. Repeating the request with the same reference message before the status returns the same request_id (details.reused: true), without a new send to the phone. A request with a different reference ends the previous one, which receives its own final status (usually timeout), and proceeds normally. 409 only occurs when the provided requestId is already in use.
The final result arrives via webhook/SSE within 2 minutes after sending the request to WhatsApp (details.result_timeout_ms). Late messages may keep arriving with the same request_id for about 5 minutes after the request, without a second final status.
Synchronous mode (sync: true)
sync: true holds the response until the result, for up to timeoutMs (default and maximum 25000). Messages come in messages, and the top of the response contains the same fields as the final status (status, has_more, history_access, received_messages, next_request), plus received, timed_out and partial:
- final result within the deadline:
200with that result; - messages arrived, but not the result:
200withstatus: "pending", about 2 seconds after the last message; - nothing arrived within the deadline:
202withstatus: "pending",timed_out: trueand emptymessages.
With status: "pending", the final result arrives later via the history webhook/SSE, with the same request_id. The webhook and SSE are also sent in synchronous mode, and messages are saved the same way.
Deleted reference message
If the anchor was deleted, the API tries to use the next valid message of that chat. details.requested_anchor_messageid reports the requested reference, details.anchor_messageid the one used, and details.anchor_replaced indicates the substitution. With no alternative, it returns HTTP 400 with status: "anchor_unavailable"; try without messageid to use the oldest saved message.
curl --request POST \
--url https://api.wppfy.com/message/history-sync \
--header 'Content-Type: application/json' \
--header 'token: <api-key>' \
--data '
{
"number": "5511999999999@s.whatsapp.net",
"messageid": "3EB01234567890ABCDEF",
"count": 20
}
'{
"success": true,
"request_id": "5f0c2a8e-6d1b-4c3a-9e7f-1a2b3c4d5e6f",
"message": "History sync request sent. Messages will be received as history sync events.",
"details": {
"result_timeout_ms": 120000,
"requested_anchor_messageid": "3EB01234567890ABCDEF",
"anchor_messageid": "3EB01234567890ABCDEF",
"anchor_replaced": false
}
}Authorizations
Body
Full chat JID.
"5511999999999@s.whatsapp.net"
ID of the reference message used to fetch older messages from the chat.
"3EB01234567890ABCDEF"
Desired number of messages in the sync.
1 <= x <= 10020
Timestamp of the reference message, in milliseconds or seconds. Optional; it comes in next_request so the reference works even before the message is saved.
1706350400000
Indicates whether the reference message was sent by the connected account. Optional; comes in next_request.
false
Optional identifier chosen by the client; when omitted, the API generates a UUID. Returned as request_id. Use a new id per request: an id already in use receives 409.
"5f0c2a8e-6d1b-4c3a-9e7f-1a2b3c4d5e6f"
Where the request is sent. try_alternates (default): in an individual conversation, sends via the chat's number and LID, because the phone stores each conversation under one of the two addresses and ignores the request sent via the other; the response arrives only once. exact: sends only via the chat's preferred address (the LID, when known). In groups, the request always goes only to the group.
try_alternates, exact Holds the response until the request result, for up to timeoutMs. See "Synchronous mode".
Only with sync: true: maximum wait in milliseconds. Larger values become 25000.
x <= 25000Response
Request sent successfully. Messages and the result arrive later via webhook/SSE. With sync: true, it also returns the messages and the request result.
true
Identifies the request. Appears in the correlated messages and in the final webhook/SSE history status.
"5f0c2a8e-6d1b-4c3a-9e7f-1a2b3c4d5e6f"
"History sync request sent. Messages will be received as history sync events."
Additional operation metadata
Show child attributes
Show child attributes
true when the response waited for the result (sync: true).
Synchronous mode only: request result; pending when it has not arrived yet and will come via webhook/SSE; blocked when the phone indicates more messages but did not deliver a page that advances (the reason comes in error).
completed, timeout, pending, blocked Synchronous mode only: chat of the request.
Synchronous mode only: what the phone declared. true there are more messages, false start of the conversation, null not confirmed. Some devices declare true in every on-demand response, even an empty one: with them, pagination ends in blocked with pagination_no_progress, never in has_more: false.
Synchronous mode only: unavailable when there are more messages without access.
available, unavailable, unknown Synchronous mode only: number of messages in messages.
Synchronous mode only: body ready to request the previous messages, or null.
Synchronous mode only: messages arrived or the request was completed.
Synchronous mode only: the timeoutMs deadline expired.
Synchronous mode only: there may still be more messages (has_more other than false).
Synchronous mode only: messages of the request, in the history event format.
With status: "blocked" (and success: false): why there is no next_request. pagination_no_progress: from the same anchor, the phone did not deliver a page that advances even at the largest count (on each page without progress, next_request doubles count, up to 100): it came back empty, without a message usable as an anchor, or repeated. This is the end of what the phone delivers from that anchor, but WhatsApp does not confirm that it is the start of the conversation; repeating the request gives the same result; anchor_unavailable: the reference message is no longer available, request with another one; history_access_unavailable: the rest is not accessible; cursor_lookup_failed: failed to build the next request, try again.
pagination_no_progress, anchor_unavailable, history_access_unavailable, cursor_lookup_failed 