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

# Register Web Push Subscription

> This endpoint allows users to register a browser's Web Push subscription.

```http theme={null}
POST /api/v1/account/notifications/web_push/subscription
```

This endpoint registers or refreshes a browser's push subscription for your account. Pacifica sends `web_push` [notifications](https://docs.pacifica.fi/api-documentation/api/rest-api/notifications) to every active subscription on the account.

Before you call it, get the VAPID public key from [Get Web Push config](https://docs.pacifica.fi/api-documentation/api/rest-api/notifications/get-web-push-config.md). Then subscribe in the browser with `pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: vapid_public_key })`.

#### Operation Type (for Signing)

| Header Field | Type | Content |
| - | - | - |
| `"type"` | string | `"register_web_push_subscription"` |

#### Request Body

<table><thead><tr><th width="200">Field</th><th width="98">Type</th><th width="95">Need</th><th>Description</th><th>Example</th></tr></thead><tbody><tr><td>`"account"`</td><td>string</td><td>required</td><td>User's wallet address</td><td>`42trU9A5...`</td></tr><tr><td>`"signature"`</td><td>string</td><td>required</td><td>Cryptographic signature</td><td>`5j1Vy9Uq...`</td></tr><tr><td>`"timestamp"`</td><td>integer</td><td>required</td><td>Current timestamp in milliseconds</td><td>`1716200000000`</td></tr><tr><td>`"installation_id"`</td><td>string</td><td>required</td><td>ID that your app generates once for this browser. 32 to 64 characters from `A-Z`, `a-z`, `0-9`, `-`, and `_`</td><td>`k3Jx9_Qm...`</td></tr><tr><td>`"endpoint"`</td><td>string</td><td>required</td><td>The subscription's `endpoint`. An `https` URL of a supported push service, up to 2048 characters</td><td>`https://fcm.googleapis.com/...`</td></tr><tr><td>`"p256dh"`</td><td>string</td><td>required</td><td>The subscription's `p256dh` key, in base64url without padding</td><td>`BNcRdreA...`</td></tr><tr><td>`"auth"`</td><td>string</td><td>required</td><td>The subscription's `auth` secret, in base64url without padding</td><td>`tBHItJI5...`</td></tr><tr><td>`"expiration_time_ms"`</td><td>integer</td><td>optional</td><td>The subscription's `expirationTime` in milliseconds. Leave it out when the browser returns `null`</td><td>`1735689600000`</td></tr><tr><td>`"vapid_public_key"`</td><td>string</td><td>required</td><td>The VAPID public key that you subscribed with</td><td>`BF6x0Kq2...`</td></tr><tr><td>`"expiry_window"`</td><td>integer</td><td>optional</td><td>Signature expiry in milliseconds</td><td>`30000`</td></tr></tbody></table>

```json theme={null}
{
  "account": "42trU9A5...",
  "signature": "5j1Vy9Uq...",
  "timestamp": 1716200000000,
  "installation_id": "k3Jx9_Qm2LpV7nRt4WcY8bZa1HdF6sGe",
  "endpoint": "https://fcm.googleapis.com/fcm/send/dX8f...",
  "p256dh": "BNcRdreA...",
  "auth": "tBHItJI5svbpez7KI4CCXg",
  "vapid_public_key": "BF6x0Kq2...",
  "expiry_window": 30000
}
```

`subscription.toJSON()` in the browser gives you `endpoint`, `keys.p256dh`, `keys.auth`, and `expirationTime` in the right format.

You must sign this request with the account key. An [agent wallet](https://docs.pacifica.fi/api-documentation/api/signing/api-agent-keys.md) can't sign it.

**Supported Push Services**

The `endpoint` host must belong to one of these push services. It must have no port, user name, password, or fragment.

| Host | Push service |
| - | - |
| `fcm.googleapis.com` | Google |
| `jmt17.google.com` | Google |
| `*.push.services.mozilla.com` | Mozilla |
| `*.push.apple.com` | Apple |
| `*.notify.windows.com` | Microsoft |

**Registration Rules**

* `installation_id` identifies one browser. Store it where the page and the service worker can both read it, for example IndexedDB.
* When you register again with the same `installation_id`, Pacifica refreshes the subscription.
* If the same `installation_id` registers under another account, the subscription moves to that account.
* If another account has an active subscription with the same `endpoint` and a different `installation_id`, the request fails with status 409. Unregister it from the other account first.
* An account keeps up to 10 active subscriptions. When you register one more, Pacifica turns off the subscription that was registered longest ago.
* `vapid_public_key` must match the current key from [Get Web Push config](https://docs.pacifica.fi/api-documentation/api/rest-api/notifications/get-web-push-config.md). If it doesn't, subscribe again with the current key.

After you register, turn on `web_push` with [Set notification master preference](https://docs.pacifica.fi/api-documentation/api/rest-api/notifications/set-notification-master-preference.md) and [Set notification preference](https://docs.pacifica.fi/api-documentation/api/rest-api/notifications/set-notification-preference.md).

#### Signing

Sign the subscription fields as the `data` object. The secret goes in `data` as `auth`. If you leave out `expiration_time_ms`, leave it out of `data` too. For the request above, the message to sign is:

```json theme={null}
{"data":{"auth":"tBHItJI5svbpez7KI4CCXg","endpoint":"https://fcm.googleapis.com/fcm/send/dX8f...","installation_id":"k3Jx9_Qm2LpV7nRt4WcY8bZa1HdF6sGe","p256dh":"BNcRdreA...","vapid_public_key":"BF6x0Kq2..."},"expiry_window":30000,"timestamp":1716200000000,"type":"register_web_push_subscription"}
```

#### Response

* Status 200: Subscription registered

```json theme={null}
{
  "success": true,
  "data": {
    "subscription_id": "3f1c2a7e-9b4d-4e8a-8c2f-6d5b1a0e9f47",
    "vapid_public_key": "BF6x0Kq2..."
  },
  "error": null,
  "code": null
}
```

<table><thead><tr><th width="208">Field</th><th width="186">Type</th><th>Description</th></tr></thead><tbody><tr><td>`"subscription_id"`</td><td>UUID</td><td>Subscription ID. Each push carries it as `subscription_id`. It stays the same when you register an active subscription again with the same account, endpoint, keys, and VAPID key. Otherwise Pacifica gives a new ID</td></tr><tr><td>`"vapid_public_key"`</td><td>string</td><td>VAPID public key of the subscription</td></tr></tbody></table>

* Status 400: Invalid request parameters or signature. The `error_id` field says why:

| `error_id` | Meaning |
| - | - |
| `invalid_notification_device_id` | `installation_id` doesn't have 32 to 64 allowed characters |
| `invalid_web_push_subscription` | `endpoint`, `p256dh`, `auth`, or `expiration_time_ms` isn't valid |
| `unsupported_web_push_service` | The `endpoint` host isn't a supported push service |

* Status 403: The account doesn't exist. An account exists after its first deposit
* Status 409: The request conflicts with the current state. The `error_id` field says why:

| `error_id` | Meaning |
| - | - |
| `web_push_key_mismatch` | `vapid_public_key` isn't the current key. Subscribe again with the current key |
| `web_push_endpoint_conflict` | Another account has an active subscription with this `endpoint` |
| `web_push_disabled` | Web Push isn't available |

```json theme={null}
{
  "success": false,
  "data": null,
  "error": "Subscription uses an old VAPID key; resubscribe with the current public key",
  "code": 409,
  "error_id": "web_push_key_mismatch"
}
```

* Status 429: Rate limit exceeded
* Status 500: Internal server error

#### Code Example (Python)

```python theme={null}
import requests

payload = {
    "account": "42trU9A5...",
    "signature": "5j1Vy9Uq...",
    "timestamp": 1716200000000,
    "installation_id": "k3Jx9_Qm2LpV7nRt4WcY8bZa1HdF6sGe",
    "endpoint": "https://fcm.googleapis.com/fcm/send/dX8f...",
    "p256dh": "BNcRdreA...",
    "auth": "tBHItJI5svbpez7KI4CCXg",
    "vapid_public_key": "BF6x0Kq2..."
}

response = requests.post(
    "/api/v1/account/notifications/web_push/subscription",
    json=payload,
    headers={"Content-Type": "application/json"}
)

data = response.json()
```


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