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

# Debug a user

> Answer "why did this user get this push, or not get one?"

Every send traces back to a rule, and every decision **not** to send is
recorded with its reason. So the question always has an exact answer.

Open **Users**, search for the user id you passed to `identify`, and open
them. You'll see:

* Their timezone, when they were last seen, and whether we can reach them
* Their devices
* Every decision made for them, with the reason
* Every notification sent, with the exact copy delivered, any custom data and
  badge it carried, and what happened after: delivered, opened, dismissed
* Their recent events, and every [lookup](https://docs.pushnotif.ai/strategy/lookups.md) run for them

For the full picture in one answer, including whether they're in the
[holdout](https://docs.pushnotif.ai/strategy/holdout.md) and which flows they're part-way through, ask
your own AI tools with `explain_user` over [MCP](https://docs.pushnotif.ai/agents/mcp.md).

## Why a push didn't send

| Reason | Means |
| - | - |
| `global_holdout` | The user is in the holdout and never gets notifications |
| `quiet_hours` | Inside the flow's quiet hours. Usually this delays the send instead. |
| `daily_cap`, `weekly_cap` | The user already got as many notifications as the flow allows, across all flows |
| `flow_cooldown` | This flow sent to the user too recently |
| `lost_arbitration` | Another, higher-priority flow matched the same event and sent instead |
| `no_registered_device` | We have no push token for any of the user's devices |
| `message_render_failed` | A `{{ variable }}` in the copy had no value |
| `message_too_large` | With its values filled in, the push was over Apple's 4 KB limit |
| `lookup_*` | A [lookup](https://docs.pushnotif.ai/strategy/lookups.md) failed, found no row, or its guard said no |
| `flow_no_longer_active` | The flow was paused or retired before the send's time came |
| `run_expired` | The user didn't finish the flow's steps in time |
| `run_in_progress` | The user was already part-way through, and the flow ignores new starts |
| `channel_not_configured` | No [APNs key](https://docs.pushnotif.ai/dashboard/apns-key.md) is installed for the workspace |

## Delivery questions

**Sent but not delivered?** Check that the
[Notification Service Extension](https://docs.pushnotif.ai/sdk/delivery-telemetry.md) is installed and the
app group is set up on both targets. Without it, delivered is never reported.

**Opened counts higher than delivered?** Same cause: opens are reported by the
app, deliveries only by the extension.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.