Start here
The 24-hour window
The single rule that decides whether a message can be free-form or must be a template. Most delivery problems are this.
WhatsApp will not deliver a free-form message from a business to a person unless that person messaged the business in the last 24 hours. Inside that window you can send whatever you like. Outside it, the only thing that reaches them is a template Meta approved in advance.
That is the whole rule. Almost every "notifications don't work" report comes back to it, because the customer a store most wants to message, the one who just checked out, is exactly the customer who has never messaged the store.
Why it exists
WhatsApp is a personal messenger. Its users did not sign up to a marketing channel, and the moment businesses can message them at will, they stop reading it, which destroys the thing that made the channel worth having.
So Meta split contact into two kinds. A conversation the customer starts is theirs, and for 24 hours you can talk in it like any other chat. A conversation the business starts has to be something the customer would recognise and want, which Meta enforces by reading the wording before you may send it. The window is where the line between those two sits.
Exactly when it opens and closes
- It opens
At the timestamp of the customer's inbound message to your number. Any inbound message, a typed reply, a tapped button, an emoji, a photo.
- It closes
Exactly 24 hours after that timestamp. Not at midnight, not at the end of a business day, 24 hours to the second from the last thing the customer sent.
- Every inbound message resets it
The window is measured from the most recent inbound message, not the first. A customer who replies on hour 23 has given you another 24 hours from that moment.
- Your own messages do not open it
Sending a template to someone does not open a window for free-form follow-ups. Only something arriving from the customer does. If they never reply, the window never opens.
- A customer who never messaged you
Has no window at all, which behaves identically to a closed one. This is the state nearly every new order is in.
What you can send on each side of it
| Situation | What can be delivered | What it costs |
|---|---|---|
| The customer messaged you in the last 24 hours, window open | Anything. Text, images, documents, location, interactive buttons and lists, or a template. | A free-form reply is a SERVICE conversation and is free, so it succeeds even on a zero balance. A template still costs its category. |
| The customer never messaged you, or the window has closed | An approved template. Nothing else. A text, image or interactive message is refused outright. | Priced by the template's category, utility, marketing or authentication. |
The practical consequence for order notifications
Every one of the 18 catalog events is a template for exactly this reason. Sending them through POST /v1/notifications/send works whether the window is open or closed, because the platform always delivers the approved template rather than guessing.
How each endpoint behaves
POST /v1/notifications/send
The window is handled for you. The event is delivered as its approved template, so it reaches the customer either way. If no approved template exists you get a stated 409 TEMPLATE_NOT_APPROVED rather than a silent non-delivery.
allowTextFallback: true lets that one case degrade to plain text, but only when the window is genuinely open. With the window closed you still get the 409, because the alternative is reporting a success for a message Meta will drop.
POST /v1/messages/send
Every message type except template is checked against the window and refused with 403 when it is closed:
{
"error": "The 24-hour customer service window is closed for this contact. Per WhatsApp policy, only an approved template message can start or re-open a conversation."
}Do not retry this. The window will not have opened a second later; it opens when the customer sends something. Send an approved template instead, or use /v1/notifications/send, which does that for you.
Seeing the window
In the Inbox, each conversation carries a badge: a countdown while the window is open, and Window closed when it is not. With the window closed, the free-form composer is disabled rather than accepting a message that would be rejected on send. The state is visible before you type, not after.

Working with it
- Send transactional events as catalog events. They are templates, so the window never applies to them.
- Answer replies promptly. A reply inside an open window is free and unrestricted; the same answer four hours after the window closes needs a template and costs money.
- Put buttons on templates you expect a response to. A tapped button is an inbound message, so it opens the window, which is how cash-on-delivery confirmation works without asking the customer to type anything.
- Do not queue free-form messages for later. A message composed while the window is open and sent after it closes is refused. Check the window at send time, not at compose time.
- Treat "never messaged us" as the default. Most of your contacts are in that state permanently, and your code should assume it.
If messages are being refused right now, Troubleshooting tells the window apart from the other causes that look identical from the outside. Message templates and approval covers getting the templates that make the window irrelevant.
