Updated on October 29, 2026
WhatsApp error 131047 means more than 24 hours have passed since the customer last messaged your number, so the customer service window is closed and free-form messages (text, media, buttons, lists) are no longer accepted. Meta’s fix is to send an approved template; when the customer replies, a new 24-hour window opens. You can avoid the error altogether by storing the time of each contact’s last inbound message and choosing between free-form text and a template before you send.
Our general guide to WhatsApp API error codes has the full code table. This article covers only 131047: why it happens, how to prevent it in code, and how to bring the customer back without overspending.
What Meta’s documentation says
In Meta’s error code table, 131047 is described as: more than 24 hours have passed since the recipient last replied to the sender number. The listed solution is to send the recipient a template message instead.
The rule behind it lives on the pricing page: when a WhatsApp user messages or calls your business, a 24-hour customer service window opens. Each new message or call from the user resets the timer. Non-template messages can only be sent while that window is open.
In practice, the error arrives asynchronously, in the status webhook, after the API has already returned a wamid:
{
"statuses": [
{
"id": "wamid.HBgLMTU1NTEyMzQ1Njc4...",
"status": "failed",
"timestamp": "1761750000",
"recipient_id": "15551234567",
"errors": [
{
"code": 131047,
"title": "More than 24 hours have passed since the recipient last replied to the sender number.",
"error_data": {
"details": "More than 24 hours have passed since the recipient last replied to the sender number."
}
}
]
}
]
}
The title and details text can change; always branch on code. That is also why a 200 OK on the send call is not enough: if you only check the synchronous response, you will think the message went out. Our article on messages that are sent but not delivered shows how to track these statuses.
When error 131047 usually shows up
The error is almost never “WhatsApp’s fault”. It shows up in flows that forget about the window:
- An agent who replies the next business day. The customer wrote on Friday at 6 p.m.; the agent answers on Monday at 9 a.m. with free-form text.
- Automation triggered by a system event. Order shipped, invoice issued, appointment rescheduled: the system sends free-form text to a contact who has not talked to the business in days.
- A bot that picks up a stalled conversation. A “still need help?” nudge sent 30 hours later.
- Migrating from an unofficial API. Teams coming from libraries like Baileys were used to texting anyone at any time. On the official WhatsApp Business API, outside the window, it is templates only.
Templates never trigger 131047. It only applies to free-form messages outside the window.
Want to try it while you read? Create a Vectalk account and send your first message through the official API. Create free account →
What opens (and reopens) the 24-hour window
According to Meta’s pricing docs, the window opens when the user sends you a message or calls your business, and every new message or call resets the 24 hours. Your own messages do not open anything: sending a template does not reopen the window by itself. The customer reopens it by replying.
What about button replies? The pricing page talks about a user message or call and does not break it down by message type. What the webhook reference does show is that a tap on a template’s quick reply button reaches the messages webhook as an inbound user message, with type: "button" and its own timestamp. That is why the code below stores the time of every inbound message, including these.
There is also the free entry point window, tied to Click-to-WhatsApp ads: when a user arrives from one of those ads (on the Android or iOS app) and you reply within the customer service window, a window that can last up to 7 days opens. While it is open, Meta does not charge for marketing, utility, authentication or service messages. Meta documents it as a pricing rule; in your code, keep deciding between free-form text and templates based on the time of the customer’s last message.
The full rules are in our guide to the WhatsApp 24-hour customer service window.
How to detect it before sending
The cheapest way to handle error 131047 is to never trigger it. Store the timestamp of every inbound message per contact and check it before any send. The Node.js example below uses an in-memory Map; in production, use a database or Redis.
const API_URL = 'https://apis.vectalk.com.br/api/messages';
const TOKEN = process.env.VECTALK_TOKEN;
const WINDOW_MS = 24 * 60 * 60 * 1000;
const SAFETY_MS = 10 * 60 * 1000; // buffer for queues and clock drift
const lastInbound = new Map(); // wa_id -> timestamp in ms
// In the webhook: store the time of the customer's last message
function onWebhook(body) {
for (const entry of body.entry || []) {
for (const change of entry.changes || []) {
for (const msg of change.value?.messages || []) {
lastInbound.set(msg.from, Number(msg.timestamp) * 1000);
}
}
}
}
function windowOpen(waId) {
const t = lastInbound.get(waId);
return t !== undefined && Date.now() - t < WINDOW_MS - SAFETY_MS;
}
async function send(payload) {
const res = await fetch(API_URL, {
method: 'POST',
headers: { Authorization: `Bearer ${TOKEN}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ messaging_product: 'whatsapp', ...payload })
});
return res.json();
}
// Pick free-form text or a template depending on the window
async function reply(waId, text, customerName) {
if (windowOpen(waId)) {
return send({ to: waId, type: 'text', text: { body: text } });
}
return send({
to: waId,
type: 'template',
template: {
name: 'resume_support',
language: { code: 'en_US' },
components: [
{ type: 'body', parameters: [{ type: 'text', text: customerName }] }
]
}
});
}
Three things to watch with this pattern:
- Use the message
timestamp, not the time the webhook arrived. Meta retries webhook deliveries, so an event can reach you late. - Keep a safety buffer. A message built at minute 1,439 of the window can go out after it expires if it sits in a queue.
- Handle the error anyway. If 131047 still arrives in the webhook, flag the message and fall back to a template instead of repeating the free-form text.
If human agents work the conversations, show the remaining window time in the agent’s screen. That alone prevents the Monday-morning reply that never arrives.
How to re-engage the customer with a template
The right template depends on why you are reaching out. The category sets the price and affects approval, and Meta has the final say on the category; see how Meta categorizes templates.
| Situation | Likely category | Sample text |
|---|---|---|
| Reply to a request the customer opened | Utility | “Hi {{1}}, we have an update on your request {{2}}. Tap See update to continue.” |
| Order, delivery or appointment update | Utility | “Your order {{1}} is out for delivery. Tap Contact the store if you need anything.” |
| Offer, coupon or invitation to buy again | Marketing | “{{1}}, we have a special deal for you. Want to take a look?” |
Two tips to actually bring the customer back:
- Add a quick reply button. Tapping is easier than typing, and the tap reaches your webhook as a message from the customer. From there, your agent or bot goes back to deciding based on the time of the last inbound message, as in the code above.
- Say why you are writing. “We have an update on your request” works better than “Hi, how are you?”, and it is easier to get approved as utility.
The full JSON for sending templates, with variables, header media and buttons, is in how to send a template through the API.
How much re-engaging costs
A message that fails with 131047 is not billed: Meta only charges for delivered messages. The cost is the template you send to fix it. Meta’s rates for messages delivered to Brazilian numbers since October 1, 2026, in Brazilian reais (BRL), are:
| Category | Price per delivered message (Brazil) |
|---|---|
| Marketing | R$ 0.3217 |
| Utility | R$ 0.0350 |
| Authentication | R$ 0.0350 |
| Service | R$ 0.0350, after 1,000 free per number per month |
Since October 1, 2026, utility templates sent inside the customer service window are also charged, and service messages (free-form replies inside the window) now come with a free tier of 1,000 per number per month. We explain the change in utility messages inside the service window.
The practical takeaway: re-engaging with utility costs a fraction of marketing. If the reason for contact is the customer’s own request, a well-written utility template fixes 131047 at the lowest price. Rates differ by destination country; see WhatsApp API pricing by country.
How to do this with Vectalk
Vectalk is a proxy for the official Cloud API, so error 131047 reaches your webhook with the same code and format Meta uses, and the example above works unchanged: sends go to POST https://apis.vectalk.com.br/api/messages with the same JSON body as Meta’s API. Templates are created in the dashboard, which includes a Template Library, or through the templates API. To review failures, filter the history with GET /api/messages?status=failed on the List Messages endpoint.
Each delivered message is deducted from your prepaid balance, and Vectalk pays Meta through its own credit line, so you never add a card to Meta. Sign up at apps.vectalk.com.br/register or read the overview in our guide to the official WhatsApp API.
Frequently asked questions
What does WhatsApp error 131047 mean?
It means more than 24 hours have passed since the customer last messaged your number. The customer service window is closed, and only approved templates can be sent until the customer replies again.
Does sending a template reopen the 24-hour window?
Not on its own. The window opens when the customer messages or calls you. The template is there to prompt that reply; once it arrives, you get another 24 hours for free-form messages.
Am I charged for a message that failed with 131047?
No. Meta only charges for delivered messages, and a message that failed with 131047 was not delivered. You only pay for the template you send afterwards, if it is delivered.
Which template should I use to restart the conversation?
If the contact is about something the customer asked for (a support answer, an order, an appointment), use a utility template, which costs R$ 0.0350 per delivered message to Brazil. If it is an offer or an invitation to buy, it is marketing, at R$ 0.3217.
Can I extend the window beyond 24 hours?
No. The customer service window lasts 24 hours from the customer’s last message or call. The free entry point window of up to 7 days for Click-to-WhatsApp ads appears on Meta’s pricing page as a billing rule.
Official sources consulted on October 29, 2026: WhatsApp Cloud API error codes, WhatsApp Business Platform pricing, Status webhook reference, Button webhook reference, Meta webhooks overview, List Messages in the Vectalk docs, Create template in the Vectalk docs.
Try the official WhatsApp API today
Create your account, generate a token and send your first message with the quick-start guide. Same payloads and webhooks as Meta's Cloud API.
