> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dmly.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Fix a message that didn't send

> Work out why a message never left DMLY — the 24-hour window, template approval, contact reachability, and what the failure actually was.

A message didn't arrive. Before you look at the contact's phone or blame the channel, work
through the checks below **in order** — they are ordered by how often each one turns out to be
the cause, and the first two account for most of them.

This page is written for WhatsApp, because that is where the rules are strictest. Messenger,
Instagram, Telegram and SMS are simpler and are called out where they differ.

<Warning>
  **A message that was never deliverable may leave no trace at all.**

  DMLY refuses to show you a message as **Sent** when it knows the send couldn't happen. That is
  deliberate — a confirmation that says "sent" when nothing left is worse than silence. But it
  has a consequence you need to know before you start looking:

  * **A reply you typed yourself** in the [Inbox](/inbox/overview) shows as failed. You will see it.
  * **An automated message** — a booking confirmation, an invoice notification, an automation
    step — can be skipped with **no message bubble and no row in Logs**. Nothing appears.

  So "there's nothing in the conversation" does not mean DMLY didn't try. It usually means DMLY
  decided it couldn't, and the reason lives somewhere other than the Inbox.
</Warning>

## Start here

| What you're looking at                                                      | Go to                                               |
| --------------------------------------------------------------------------- | --------------------------------------------------- |
| The contact wrote to you within the last day, and the reply still didn't go | [Reachability](#3-is-the-contact-reachable-at-all)  |
| The contact last wrote days ago, and nothing you send arrives               | [The 24-hour window](#1-the-24-hour-window)         |
| Booking confirmations and invoice notifications never arrive, for anyone    | [Template approval](#2-template-approval)           |
| You can see a failed message with an error on it                            | [Permanent or retryable](#4-permanent-or-retryable) |
| It works for some contacts and not others                                   | [Reachability](#3-is-the-contact-reachable-at-all)  |

## 1. The 24-hour window

WhatsApp only lets you send a free-form message to someone **within 24 hours of their last
message to you**. Outside that window, the only thing WhatsApp accepts is an approved template.
This is Meta's rule, not DMLY's, and nothing in DMLY can widen it.

So the first question is always: **when did this contact last message you?** Open the
conversation in the [Inbox](/inbox/overview) and look at the timestamp on their last inbound
message. If it is more than a day old, the window is closed, and:

* A **free-form** message will not go.
* An **approved template** will.

See [WhatsApp limits](/channels/whatsapp-limits) for the window and the messaging tiers in full.

<Note>
  This is why the same automation can look reliable for weeks and then appear broken. Nothing
  changed — the contacts changed. A contact who just wrote to you gets the message; a contact who
  went quiet three days ago doesn't.
</Note>

## 2. Template approval

If the window is closed, everything depends on whether Meta has **approved** the template DMLY
wants to use. DMLY ships a set of its own system templates for things like booking
confirmations and invoice notifications — their names all start with `dmly_` — and submits them
to Meta when you connect a WhatsApp number.

**DMLY will only use a template Meta has approved.** Not one that is pending, not one that was
rejected. That leaves three outcomes for any automated WhatsApp notification:

| State of the template                                               | What happens                                                                       |
| ------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| **Approved**                                                        | The message goes, window open or closed. This is the working state.                |
| **Not approved, but the contact messaged you in the last 24 hours** | DMLY sends a free-form message instead. It arrives.                                |
| **Not approved, and the window is closed**                          | **The message is skipped entirely.** Nothing is sent and no failed bubble appears. |

That last row is the single biggest cause of "the notification never arrived." It is a
deliberate choice: sending a free-form message outside the window would be silently rejected by
Meta and would show in DMLY as a phantom **Sent**. Skipping is honest; it's just quiet.

### Check and fix it

Open your WhatsApp **Templates** and look at every template whose name starts with `dmly_`. Any
that is not approved is a hole in your notifications.

<Steps>
  <Step title="Select Refresh templates">
    **Refresh templates** re-reads the real state from Meta and re-submits anything that never
    made it there. This matters because a template can show as pending in DMLY while Meta has no
    record of it at all — it looks like it's waiting on Meta, but nothing is. **Refresh
    templates** repairs that.
  </Step>

  <Step title="Give Meta time, then check again">
    A genuinely submitted template is waiting on Meta's review. Refreshing again later is how you
    find out it landed.
  </Step>

  <Step title="If templates can't be submitted yet">
    Templates can only be submitted once a live WhatsApp number is connected. If you connected
    recently or the number isn't fully live, fix that first — see
    [Connect WhatsApp](/channels/whatsapp).
  </Step>
</Steps>

<Note>
  Your own templates for [Broadcasts](/broadcasts/overview) follow exactly the same approval
  rule. See [message templates](/broadcasts/message-templates).
</Note>

<Warning>
  **You cannot diagnose a skipped notification from the Logs page.** When DMLY skips a WhatsApp
  notification for a pending template and a closed window, no row is written to **Configurations →
  Logs**. There is nothing to find. If you have worked through the window and the template state
  and still can't explain it, that gap is why — the template state on the **Templates** page is
  the answer, not Logs.
</Warning>

## 3. Is the contact reachable at all?

If it works for some contacts and not others, the contact is the variable. DMLY treats a contact
as unreachable on a channel if **any** of these is true:

* **They opted out.** An opt-out blocks messaging on every channel, permanently, until it's
  reversed. See [contacts and privacy](/contacts/data-and-privacy).
* **They're blocked.** A blocked contact is never messaged.
* **They have no identity on that channel.** A contact with a phone number is not automatically
  a WhatsApp contact — DMLY needs to have actually reached them on WhatsApp, or matched them to
  it, before it can send there.
* **The messaging window is closed** — check 1 again.

<Warning>
  **The reachable filter on the contacts list is looser than the rule automations use.** The
  filter only checks whether the contact has an identity on the channel. An automation also
  checks opt-out, blocked status and the window. So a contact can appear reachable in the list
  and still be skipped by an automation. Don't use the list to prove a contact is messageable.
</Warning>

### Automations won't move a contact onto WhatsApp

DMLY is WhatsApp-first, but not at the cost of hijacking a conversation. An automated
notification only uses WhatsApp if the contact is **already** a WhatsApp contact, or has no
channel yet. A contact who came in through Telegram, Messenger or SMS keeps their own channel
even if you have their phone number.

The practical consequence: a contact with no channel at all and no phone number — an imported row
with only an email, say — has nowhere for an automated message to go. It is skipped, silently. (A
channel-less lead who *does* have a phone number is fine: if a WhatsApp number is connected, DMLY
attaches that phone to WhatsApp and sends there.)

## 4. Permanent or retryable

Once you have an actual failure to look at, the question is whether it will fix itself.

**Retryable** — a rate limit. A rate-limited broadcast is put back in the queue and tried again a
few seconds later, and writes nothing to Logs while it waits. A timeout or an outage at Meta is
*not* retried — it is recorded as a permanent failure straight away.

**Permanent** — the send will never succeed as-is, and DMLY records it. This is a `send_failed`
row on the [Logs page](/troubleshooting/logs), and it carries the raw reason from Meta, which is
what you act on.

Some failures are a missing setup rather than a bad recipient. The reason recorded on the
message tells you which:

| Reason                                    | What it actually means                                                                                                                                          |
| ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `no_credentials` on WhatsApp              | The WhatsApp channel isn't connected, or its credentials are gone. See [Connect WhatsApp](/channels/whatsapp).                                                  |
| `no_credentials` on Facebook or Instagram | The same, for that Meta channel. Reconnect it — see [Channels](/channels/overview).                                                                             |
| `no_gateway` on SMS                       | **Your SMS provider isn't connected** — this is not a bad phone number. Connect Twilio, Plivo or a custom gateway under [Integrations](/integrations/overview). |
| `no_active_channel`                       | DMLY had no channel to send on. The contact isn't attached to a connected channel — see [Reachability](#3-is-the-contact-reachable-at-all).                     |

All four are workspace setup, not the contact. None of them will resolve on their own.

## 5. What Logs shows

Open **Configurations → Logs**, select **Filters**, and set **Status** to **Error** — leave
**Event** on **All events** (or set it to **Errors**; a failed send is logged as an Errors-type
event, not a Messages one). Then read [the Logs page guide](/troubleshooting/logs) for what the
rows mean — but two traps matter here specifically.

<Warning>
  **Logs only ever shows the channel you currently have selected.** If you are chasing a send on
  a channel you don't have selected, you will see an empty list and conclude nothing happened.
  Switch the channel first, then read the list.
</Warning>

**And silence in Logs is not proof.** By this point on the page you know three separate ways a
message can fail to arrive without writing a single row:

* It was skipped for a pending template with the window closed.
* It was skipped because the contact wasn't reachable — no record at all.
* It's mid-retry — nothing is written until it fails permanently.

That's why the order on this page matters. Logs is where you finish, not where you start.

## Next

<Columns cols={2}>
  <Card title="Reading the Logs page" icon="clipboard-list" href="/troubleshooting/logs">
    What a `send_failed` row is, and the entries that never appear.
  </Card>

  <Card title="WhatsApp limits" icon="gauge-high" href="/channels/whatsapp-limits">
    The 24-hour window and the messaging tiers, in full.
  </Card>

  <Card title="Message templates" icon="file-lines" href="/broadcasts/message-templates">
    How approval works, and what Meta rejects.
  </Card>

  <Card title="Automation not triggering" icon="bolt" href="/troubleshooting/automation-not-triggering">
    When the bot never got as far as sending anything.
  </Card>
</Columns>
