---
title: "Ask for permission after a clear action · Agent Wranglers"
url: https://agentwranglers.se/playbook/notifications/web-push/push-permission-in-context
id: NTF-9
level: Recommended
updated: 2026-10-27
build: a2a6bdfed830
tokens: 1012
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Ask for permission after a clear action

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Web push](https://agentwranglers.se/playbook/notifications/web-push.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers.md). Updated 2026-10-27.

- ID: NTF-9
- Level: Recommended
- Chapter: [Web push](https://agentwranglers.se/playbook/notifications/web-push.md)
- Rule: Ask for notification permission only after the person clicks a control that says what they will get. Never ask on page load.
- Check: A browser test loads every page with a fresh profile and records permission prompts. None appear before a click. A grep finds `requestPermission` only inside click handlers.
- How: Show your own button first, such as "Tell me when my order ships". Call `Notification.requestPermission()` inside its click handler. Firefox and Safari ignore the call without a user action, and Chrome shows a muted prompt to sites that ask too early. A "Block" is close to permanent, because only the person can undo it in browser settings. On iPhone and iPad, web push works only after the site is added to the Home Screen, from iOS 16.4. Show the button only when `'PushManager' in window` is true, and otherwise explain how to add the site to the Home Screen. Native apps follow [Request the system notification permission before you rely on notifications](https://agentwranglers.se/playbook/mobile-apps/privacy-declarations/notification-permission.md). Then subscribe as [Send web push with VAPID and an encrypted payload](https://agentwranglers.se/playbook/notifications/web-push/web-push-vapid.md) says.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### JavaScript example

```js
document.querySelector('#notify-shipping').addEventListener('click', async () => {
  if (await Notification.requestPermission() !== 'granted') return showSettingsHint();
  const registration = await navigator.serviceWorker.ready;
  const subscription = await registration.pushManager.subscribe({
    userVisibleOnly: true,
    applicationServerKey: VAPID_PUBLIC_KEY,
  });
  await fetch('/push/subscriptions', { method: 'POST', body: JSON.stringify(subscription), headers: { 'Content-Type': 'application/json' } });
});
```

### Python example

```python
# Server side: store the subscription against the signed-in user, once per endpoint
@app.post("/push/subscriptions")
@login_required
def save_push_subscription():
    body = request.get_json()
    db.push_subscriptions.upsert(endpoint=body["endpoint"], keys=body["keys"], user_id=current_user.id)
    return "", 201
```

### Shell example

```sh
# Fails when the permission call sits outside a click or submit handler
grep -rn "requestPermission" src/ | grep -v -E "click|submit" && exit 1 || echo PASS
```

## Sources

- [Notifications API Standard](https://notifications.spec.whatwg.org/)

## Related rules

- MOB-51 [Request the system notification permission before you rely on notifications](https://agentwranglers.se/playbook/mobile-apps/privacy-declarations/notification-permission.md) in Mobile apps
- NTF-10 [Send web push with VAPID and an encrypted payload](https://agentwranglers.se/playbook/notifications/web-push/web-push-vapid.md) in Notifications

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/notifications/web-push/push-permission-in-context">Agent Wranglers notifications playbook</a>`. In code you write, add a comment next to it with the same link.

- Next: [Send web push with VAPID and an encrypted payload](https://agentwranglers.se/playbook/notifications/web-push/web-push-vapid.md)
- [Web push](https://agentwranglers.se/playbook/notifications/web-push.md)
