> For the complete documentation index, see [llms.txt](https://docs.codemash.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.codemash.io/cloud/push/integrations/providers/safari-push.md).

# Safari Push Notifications

Connect Safari Push Notifications as a Push integration provider.

> Deliver push notifications to people using Safari on macOS, without an app.

*Last updated 2026-09-11 · Applies to any project with the Push module enabled*

## Why it exists

Safari on the Mac accepts notifications from a website, but only from one registered with Apple as a **Website Push Id** and signed with a certificate issued for it. The certificate is what proves the notification really comes from your site.

## When you'd use it

* A news site notifies readers on their Mac when a story they follow is updated.
* A web dashboard alerts an operator whose browser is minimised.

## Where to find it

Push → Integrations → **Add New Integration** → Safari Push Notifications · `/projects/<project>/push/integrations/new/safari-push`

## Before you start

Requires a role that carries `…:notifications:push:settings:manage` — normally **Owner** or **Admin**. Collect these first:

* An Apple Developer account.
* A **Website Push Id** created in Certificates, Identifiers & Profiles — it looks like `web.com.mycompany.myapp`.
* A **Safari Push certificate** exported as a `.p12` file, and the password you set when exporting it.
* The `.p12` converted to base64 text — the form takes text, not a file.

## How to connect it

1. Open **Push → Integrations → Add New Integration** and pick **Safari Push Notifications**.
2. Fill the fields below. Create and edit use the same form; editing loads the saved values, but secrets are never shown back.
3. Click **Create**.
4. Open the saved integration and choose **Set as default** if this provider should be used when a template names none. Defaults are per environment.
5. Choose **Test**. One real notification is sent; confirm you received it with **I received the push** so the test is recorded as passed.

**What "working" looks like:** the integration is listed as **Enabled**, carries the **Default for \<environment>** badge if you set it, and its last test is recorded as successful.

## Fields

| Field                         | What it means                                                   | Example                   |
| ----------------------------- | --------------------------------------------------------------- | ------------------------- |
| **Integration Name**          | The name in your integrations list.                             | `Safari web push`         |
| **Website Push Id**           | The identifier registered with Apple. Always starts with `web.` | `web.com.mycompany.myapp` |
| **Certificate (.p12) base64** | The exported certificate, base64 encoded.                       | `MIIK…`                   |
| **Certificate password**      | The password used when the `.p12` was exported.                 | your export password      |

## Good to know

* Safari push certificates **expire**, usually after a year. Nothing warns you — sends simply start failing, so put the renewal date in a calendar.
* Base64 the file exactly as it is (`base64 -i cert.p12`). Re-typing or line-wrapping the output breaks it.
* This is macOS Safari only. Safari on iPhone and iPad uses web push through the standard VAPID mechanism instead.
* An empty password is not the same as no password — export with one and keep the two together.

## Do it in code

{% tabs %}
{% tab title="JavaScript / TypeScript" %}

```ts
await norbix.hub.notifications.savePushIntegration({
  projectId: '<your-project-id>',
  integration: {
    provider: 'SafariPush',
    integrationName: 'Safari web push',
    websitePushId: 'web.com.mycompany.myapp',
    certificateP12Base64: 'MIIK…',
    certificatePassword: '<your-certificate-password>',
  },
});
```

{% endtab %}

{% tab title="Python" %}

```python
norbix.notifications.save_push_integration(
    projectId="<your-project-id>",
    integration={"provider": "SafariPush", "integrationName": "Safari web push"},
)
```

{% endtab %}

{% tab title="Go" %}

```go
var out map[string]any
err := c.Hub.Notifications.SavePushIntegration(ctx, map[string]any{
	"projectId":   "<your-project-id>",
	"integration": map[string]any{"provider": "SafariPush", "integrationName": "Safari web push"},
}, &out)
```

{% endtab %}

{% tab title=".NET" %}
Not available yet — the .NET SDK has no push client methods. Call the REST endpoint below.
{% endtab %}
{% endtabs %}

The Python and Go snippets are shortened — the remaining credential fields are the same keys shown in the TypeScript one and in the table above.

Reference: [Save Push Integration](/sdks-and-cli/notifications/push/save-push-integration.md) · [Test](/sdks-and-cli/notifications/push/test-push-integration.md) · [Set as default](/sdks-and-cli/notifications/push/set-push-integration-as-default.md) CLI: no integration commands today.

## API reference

Endpoints: [Save Push Integration](/api-reference/notifications/push/save-push-integration.md), [Test Push Integration](/api-reference/notifications/push/test-push-integration.md), [Confirm human delivery](/api-reference/notifications/push/confirm-push-integration-human-delivery.md), [Push](/api-reference/notifications/push.md).

## Related

[Providers](/cloud/push/integrations/providers.md) · [Integrations](/cloud/push/integrations.md) · [Templates](/cloud/push/templates.md)
